Skip to content

Commit 72dfe72

Browse files
committed
Merge pull request #56 from pocket7878/deref
Deref
2 parents 929617d + e89d3f8 commit 72dfe72

File tree

1 file changed

+75
-37
lines changed

1 file changed

+75
-37
lines changed

1.6/ja/book/deref-coercions.md

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
% `Deref` coercions
1+
% `Deref` による型強制
2+
<!-- % `Deref` coercions -->
23

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` は通常、参照外し演算子 `*` をオーバーロードするために利用されます。
58

69
```rust
710
use std::ops::Deref;
@@ -26,71 +29,101 @@ fn main() {
2629

2730
[deref]: ../std/ops/trait.Deref.html
2831

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+
例えば:
3341

3442
```rust
3543
fn foo(s: &str) {
36-
// borrow a string for a second
44+
# // // borrow a string for a second
45+
// 一瞬だけ文字列を借用します
3746
}
3847

39-
// String implements Deref<Target=str>
48+
# // // String implements Deref<Target=str>
49+
// String は Deref<Target=str> を実装しています
4050
let owned = "Hello".to_string();
4151

42-
// therefore, this works:
52+
# // // therefore, this works:
53+
// なので、以下のコードはきちんと動作します:
4354
foo(&owned);
4455
```
4556

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>` を実装しているため、以下のコードは正しく動作します:
5371

5472
```rust
5573
use std::rc::Rc;
5674

5775
fn foo(s: &str) {
58-
// borrow a string for a second
76+
# // // borrow a string for a second
77+
// 文字列を一瞬だけ借用します
5978
}
6079

61-
// String implements Deref<Target=str>
80+
# // // String implements Deref<Target=str>
81+
// String は Deref<Target=str>を実装しています
6282
let owned = "Hello".to_string();
6383
let counted = Rc::new(owned);
6484

65-
// therefore, this works:
85+
# // // therefore, this works:
86+
// ゆえに、以下のコードは正しく動作します:
6687
foo(&counted);
6788
```
6889

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はこのような変換を型がマッチするまで必要なだけ繰り返します。
74100

75-
Another very common implementation provided by the standard library is:
101+
<!-- Another very common implementation provided by the standard library is: -->
102+
標準ライブラリに頻繁に見られるその他の実装は例えば以下の様なものが有ります:
76103

77104
```rust
78105
fn foo(s: &[i32]) {
79-
// borrow a slice for a second
106+
# // // borrow a slice for a second
107+
// スライスを一瞬だけ借用します
80108
}
81109

82-
// Vec<T> implements Deref<Target=[T]>
110+
# // // Vec<T> implements Deref<Target=[T]>
111+
// Vec<T> は Deref<Target=[T]> を実装しています
83112
let owned = vec![1, 2, 3];
84113

85114
foo(&owned);
86115
```
87116

88-
Vectors can `Deref` to a slice.
117+
<!-- Vectors can `Deref` to a slice. -->
118+
ベクタはスライスに `Deref` することができます。
89119

90-
## Deref and method calls
120+
<!-- ## Deref and method calls -->
121+
## Derefとメソッド呼び出し
91122

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+
例えば以下の様なコードを見てみましょう:
94127

95128
```rust
96129
struct Foo;
@@ -104,8 +137,10 @@ let f = &&Foo;
104137
f.foo();
105138
```
106139

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+
これは、以下が全て等価なことによります:
109144

110145
```rust,ignore
111146
f.foo();
@@ -114,6 +149,9 @@ f.foo();
114149
(&&&&&&&&f).foo();
115150
```
116151

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

Comments
 (0)