[[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