アンサイズ (dyn
抽象化や配列のスライス化など) について。
アンサイズまわりの挙動の説明のため、専用のトレイトが導入されている。
しかし、、これらはナイトリー版でのみ使える不安定な機能である。そのため、安定版ではこの機能はユーザ定義の型に使えず、組込型の特権となっている。
Unsized
条件を満たす型にコンパイラが自動で付加する。
以下のような変換を可能にする。
[T;n]
→ [T]
T
→ dyn U
CoerceUnsized
アンサイズ関連の変換に対応したい場合に付加する。
参照先がアンサイズ可能な型なら、参照先のアンサイズに対応する実装が多い。
例えば、組込型 (安定版ではこれが全て) では以下がある。
&T
&mut T
Box<T>
Rc<T>
Weak<T>
Cell<T>
RefCell<T>
以下では、ナイトリー版でのスマートポインタの実装例を示している。
MyPtr
は CoerceUnsized
を実装しているため、参照先を dyn
で抽象化できる。
#![feature(unsize)]
#![feature(coerce_unsized)]
use std::marker::Unsize;
use std::ops::{CoerceUnsized, Deref};
fn main() {
let val = MyPtr(Box::new(42));
let val = val as MyPtr<dyn ToString>;
assert_eq!(val.to_string(), "42");
}
struct MyPtr<T: ?Sized>(Box<T>);
impl<T: ?Sized> Deref for MyPtr<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.deref()
}
}
impl<T, U> CoerceUnsized<MyPtr<U>> for MyPtr<T>
where
T: Unsize<U> + ?Sized,
U: ?Sized,
{
// nop.
}