1
- % ` Deref ` coercions
1
+ % ` Deref ` による型強制
2
+ <!-- % `Deref` coercions -->
2
3
3
- The standard library provides a special trait, [ ` Deref ` ] [ deref ] . It’s normally
4
- used to overload ` * ` , the dereference operator:
4
+ <!-- The standard library provides a special trait, [`Deref`][deref]. It’s normally -->
5
+ <!-- used to overload `*`, the dereference operator: -->
6
+ 標準ライブラリは特別なトレイト [ ` Dref ` ] [ deref ] を提供します。
7
+ ` Deref ` は通常、参照外し演算子 ` * ` をオーバーロードするために利用されます。
5
8
6
9
``` rust
7
10
use std :: ops :: Deref ;
@@ -26,71 +29,101 @@ fn main() {
26
29
27
30
[ deref ] : ../std/ops/trait.Deref.html
28
31
29
- This is useful for writing custom pointer types. However, there’s a language
30
- feature related to ` Deref ` : ‘deref coercions’. Here’s the rule: If you have a
31
- type ` U ` , and it implements ` Deref<Target=T> ` , values of ` &U ` will
32
- automatically coerce to a ` &T ` . Here’s an example:
32
+ <!-- This is useful for writing custom pointer types. However, there’s a language -->
33
+ <!-- feature related to `Deref`: ‘deref coercions’. Here’s the rule: If you have a -->
34
+ <!-- type `U`, and it implements `Deref<Target=T>`, values of `&U` will -->
35
+ <!-- automatically coerce to a `&T`. Here’s an example: -->
36
+ このように、 ` Deref ` はカスタマイズしたポインタ型を定義するのに便利です。
37
+ 一方で、` Deref ` に関連する機能がもう一つ有ります: 「derefによる型強制」です。
38
+ これは、 ` Deref<Target=T> ` を実装している型 ` U ` があるときに、
39
+ ` &U ` が自動的に ` &T ` に型強制されるというルールです。
40
+ 例えば:
33
41
34
42
``` rust
35
43
fn foo (s : & str ) {
36
- // borrow a string for a second
44
+ # // // borrow a string for a second
45
+ // 一瞬だけ文字列を借用します
37
46
}
38
47
39
- // String implements Deref<Target=str>
48
+ # // // String implements Deref<Target=str>
49
+ // String は Deref<Target=str> を実装しています
40
50
let owned = " Hello" . to_string ();
41
51
42
- // therefore, this works:
52
+ # // // therefore, this works:
53
+ // なので、以下のコードはきちんと動作します:
43
54
foo (& owned );
44
55
```
45
56
46
- Using an ampersand in front of a value takes a reference to it. So ` owned ` is a
47
- ` String ` , ` &owned ` is an ` &String ` , and since `impl Deref<Target=str> for
48
- String` , ` &String` will deref to ` &str` , which ` foo()` takes.
49
-
50
- That’s it. This rule is one of the only places in which Rust does an automatic
51
- conversion for you, but it adds a lot of flexibility. For example, the ` Rc<T> `
52
- type implements ` Deref<Target=T> ` , so this works:
57
+ <!-- Using an ampersand in front of a value takes a reference to it. So `owned` is a -->
58
+ <!-- `String`, `&owned` is an `&String`, and since `impl Deref<Target=str> for -->
59
+ <!-- String`, `&String` will deref to `&str`, which `foo()` takes. -->
60
+ 値の前にアンパサンド(&)をつけることによってその値への参照を取得することができます。
61
+ なので、 ` owned ` は ` String ` であり、 ` &owned ` は ` &String ` であり、
62
+ そして、 ` String ` が ` Deref<Target=str> ` を実装しているために、
63
+ ` &String ` は ` foo() ` が要求している ` &str ` に型強制されます。
64
+
65
+ <!-- That’s it. This rule is one of the only places in which Rust does an automatic -->
66
+ <!-- conversion for you, but it adds a lot of flexibility. For example, the `Rc<T>` -->
67
+ <!-- type implements `Deref<Target=T>`, so this works: -->
68
+ 以上です! このルールはRustが自動的に変換を行う唯一の箇所の一つです。
69
+ これによって、多くの柔軟性が手にはいります。
70
+ 例えば ` Rc<T> ` は ` Deref<Target=T> ` を実装しているため、以下のコードは正しく動作します:
53
71
54
72
``` rust
55
73
use std :: rc :: Rc ;
56
74
57
75
fn foo (s : & str ) {
58
- // borrow a string for a second
76
+ # // // borrow a string for a second
77
+ // 文字列を一瞬だけ借用します
59
78
}
60
79
61
- // String implements Deref<Target=str>
80
+ # // // String implements Deref<Target=str>
81
+ // String は Deref<Target=str>を実装しています
62
82
let owned = " Hello" . to_string ();
63
83
let counted = Rc :: new (owned );
64
84
65
- // therefore, this works:
85
+ # // // therefore, this works:
86
+ // ゆえに、以下のコードは正しく動作します:
66
87
foo (& counted );
67
88
```
68
89
69
- All we’ve done is wrap our ` String ` in an ` Rc<T> ` . But we can now pass the
70
- ` Rc<String> ` around anywhere we’d have a ` String ` . The signature of ` foo `
71
- didn’t change, but works just as well with either type. This example has two
72
- conversions: ` Rc<String> ` to ` String ` and then ` String ` to ` &str ` . Rust will do
73
- this as many times as possible until the types match.
90
+ <!-- All we’ve done is wrap our `String` in an `Rc<T>`. But we can now pass the -->
91
+ <!-- `Rc<String>` around anywhere we’d have a `String`. The signature of `foo` -->
92
+ <!-- didn’t change, but works just as well with either type. This example has two -->
93
+ <!-- conversions: `Rc<String>` to `String` and then `String` to `&str`. Rust will do -->
94
+ <!-- this as many times as possible until the types match. -->
95
+ 先ほどのコードとの変化は ` String ` を ` Rc<T> ` でラッピングした点ですが、
96
+ 依然 ` Rc<String> ` を ` String ` が必要なところに渡すことができます。
97
+ ` foo ` のシグネチャは変化していませんが、どちらの型についても正しく動作します。
98
+ この例は2つの変換を含んでいます: ` Rc<String> ` が ` String ` に変換され、次に ` String ` が ` &str ` に変換されます。
99
+ Rustはこのような変換を型がマッチするまで必要なだけ繰り返します。
74
100
75
- Another very common implementation provided by the standard library is:
101
+ <!-- Another very common implementation provided by the standard library is: -->
102
+ 標準ライブラリに頻繁に見られるその他の実装は例えば以下の様なものが有ります:
76
103
77
104
``` rust
78
105
fn foo (s : & [i32 ]) {
79
- // borrow a slice for a second
106
+ # // // borrow a slice for a second
107
+ // スライスを一瞬だけ借用します
80
108
}
81
109
82
- // Vec<T> implements Deref<Target=[T]>
110
+ # // // Vec<T> implements Deref<Target=[T]>
111
+ // Vec<T> は Deref<Target=[T]> を実装しています
83
112
let owned = vec! [1 , 2 , 3 ];
84
113
85
114
foo (& owned );
86
115
```
87
116
88
- Vectors can ` Deref ` to a slice.
117
+ <!-- Vectors can `Deref` to a slice. -->
118
+ ベクタはスライスに ` Deref ` することができます。
89
119
90
- ## Deref and method calls
120
+ <!-- ## Deref and method calls -->
121
+ ## Derefとメソッド呼び出し
91
122
92
- ` Deref ` will also kick in when calling a method. Consider the following
93
- example.
123
+ <!-- `Deref` will also kick in when calling a method. Consider the following -->
124
+ <!-- example. -->
125
+ ` Deref ` はメソッド呼び出し時にも自動的に呼びだされます。
126
+ 例えば以下の様なコードを見てみましょう:
94
127
95
128
``` rust
96
129
struct Foo ;
@@ -104,8 +137,10 @@ let f = &&Foo;
104
137
f . foo ();
105
138
```
106
139
107
- Even though ` f ` is a ` &&Foo ` and ` foo ` takes ` &self ` , this works. That’s
108
- because these things are the same:
140
+ <!-- Even though `f` is a `&&Foo` and `foo` takes `&self`, this works. That’s -->
141
+ <!-- because these things are the same: -->
142
+ ` f ` は ` &&Foo ` であり、 ` foo ` は ` &self ` を引数に取るにも関わらずこのコードは動作します。
143
+ これは、以下が全て等価なことによります:
109
144
110
145
``` rust,ignore
111
146
f.foo();
@@ -114,6 +149,9 @@ f.foo();
114
149
(&&&&&&&&f).foo();
115
150
```
116
151
117
- A value of type ` &&&&&&&&&&&&&&&&Foo ` can still have methods defined on ` Foo `
118
- called, because the compiler will insert as many * operations as necessary to
119
- get it right. And since it’s inserting ` * ` s, that uses ` Deref ` .
152
+ <!-- A value of type `&&&&&&&&&&&&&&&&Foo` can still have methods defined on `Foo` -->
153
+ <!-- called, because the compiler will insert as many * operations as necessary to -->
154
+ <!-- get it right. And since it’s inserting `*`s, that uses `Deref`. -->
155
+ ` &&&&&&&&&&&&&&&&Foo ` 型の値は ` Foo ` で定義されているメソッドを呼び出すことができます。
156
+ これは、コンパイラが自動的に必要なだけ * 演算子を補うことによります。
157
+ そして ` * ` が補われることによって ` Deref ` が利用される事になります。
0 commit comments