|
| 1 | +<!-- |
1 | 2 | # Returning Traits with `dyn`
|
| 3 | +--> |
| 4 | +# `dyn`を利用してトレイトを返す |
2 | 5 |
|
| 6 | +<!-- |
3 | 7 | The Rust compiler needs to know how much space every function's return type requires. This means all your functions have to return a concrete type. Unlike other languages, if you have a trait like `Animal`, you can't write a function that returns `Animal`, because its different implementations will need different amounts of memory.
|
| 8 | +--> |
| 9 | +Rustのコンパイラはあらゆる関数のリターン型に必要なスペースを知っておく必要があります。 |
| 10 | +つまり、すべての関数は具体的な型を返す必要があるのです。 |
| 11 | +他の言語と違って、`Animal`のようなトレイトがある場合に、`Animal`を返す関数を書くことはできません。 |
| 12 | +なぜなら、そのトレイトの異なる実装はそれぞれ別の量のメモリを必要とするからです。 |
4 | 13 |
|
| 14 | +<!-- |
5 | 15 | However, there's an easy workaround. Instead of returning a trait object directly, our functions return a `Box` which _contains_ some `Animal`. A `box` is just a reference to some memory in the heap. Because a reference has a statically-known size, and the compiler can guarantee it points to a heap-allocated `Animal`, we can return a trait from our function!
|
| 16 | +--> |
| 17 | +しかし、簡単な回避策があります。 |
| 18 | +直接トレイトオブジェクトを返す代わりに、`Animal`を _含む_ `Box`を返すのです。 |
| 19 | +`Box`はヒープ中のメモリへの単なる参照です。 |
| 20 | +参照のサイズは静的に知ることができ、コンパイラは参照がヒープに割り当てられた`Animal`を指していると保証できるので、私たちは関数からトレイトを返すことができます。 |
6 | 21 |
|
| 22 | +<!-- |
7 | 23 | Rust tries to be as explicit as possible whenever it allocates memory on the heap. So if your function returns a pointer-to-trait-on-heap in this way, you need to write the return type with the `dyn` keyword, e.g. `Box<dyn Animal>`.
|
| 24 | +--> |
| 25 | +ヒープにメモリを割り当てる際、Rustは可能な限り明示的であろうとします。 |
| 26 | +なので、もしあなたの関数がヒープ上のトレイトへのポインタを返す場合、例えば`Box<dyn Animal>`のように、リターン型に`dyn`キーワードをつける必要があります。 |
8 | 27 |
|
9 | 28 | ```rust,editable
|
10 | 29 | struct Sheep {}
|
11 | 30 | struct Cow {}
|
12 | 31 |
|
13 | 32 | trait Animal {
|
14 | 33 | // Instance method signature
|
| 34 | + // インスタンスのメソッドシグネチャ |
15 | 35 | fn noise(&self) -> &'static str;
|
16 | 36 | }
|
17 | 37 |
|
18 | 38 | // Implement the `Animal` trait for `Sheep`.
|
| 39 | +// `Sheep`に`Animal`トレイトを実装する。 |
19 | 40 | impl Animal for Sheep {
|
20 | 41 | fn noise(&self) -> &'static str {
|
21 | 42 | "baaaaah!"
|
22 | 43 | }
|
23 | 44 | }
|
24 | 45 |
|
25 | 46 | // Implement the `Animal` trait for `Cow`.
|
| 47 | +// `Cow`に`Animal`トレイトを実装する。 |
26 | 48 | impl Animal for Cow {
|
27 | 49 | fn noise(&self) -> &'static str {
|
28 | 50 | "moooooo!"
|
29 | 51 | }
|
30 | 52 | }
|
31 | 53 |
|
32 | 54 | // Returns some struct that implements Animal, but we don't know which one at compile time.
|
| 55 | +// Animalを実装した何らかの構造体を返す。 |
| 56 | +// ただし、コンパイル時にはどの実装か分からない。 |
33 | 57 | fn random_animal(random_number: f64) -> Box<dyn Animal> {
|
34 | 58 | if random_number < 0.5 {
|
35 | 59 | Box::new(Sheep {})
|
|
0 commit comments