[[Rust]]の[[参照外し型強制]]について、定義が抽象的なので分かりにくいため、もう少し具体的な話をする。
## 具体的な定義
データ型`T`が`Deref<Target=U>`を実装しているなら、`&T`は`&U`に型強制される。
## 具体例
まだ分かりにくいので具体例を挙げる。以下のような`MyBox`構造体を考える。
```rust
use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> {
MyBox(x)
}
}
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
```
先の例に当てはめると
- `MyBox<T>`が`Deref<Target=T>`を実装しているなら、`&MyBox<T>`は`&T`に型強制される
- `T = String`のとき、`&T`の引数に`&MyBox<String>`型を入れても問題ない
と言える。よって以下が成り立つ。
```rust
fn hello(name: &String) {
eprintln!("Hello = {:?}", name);
}
fn main() {
let x = String::from("おはよう");
let y = MyBox::new(x);
hello(&y);
assert_eq!(String::from("おはよう"), *y);
}
```
なお、`hello(name: &str)`でもコンパイルは通る。これは更に[[参照外し型強制]]が行われているからである。
- `String`が`Deref<Target=str>`を実装しているため、`&String`は`&str`に型強制される
```rust
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for String {
type Target = str;
#[inline]
fn deref(&self) -> &str {
unsafe { str::from_utf8_unchecked(&self.vec) }
}
}
```
## 参考
- http://www.nct9.ne.jp/m_hiroi/linux/rustabc03.html