アンサイズ (dyn 抽象化や配列のスライス化など) について。

背景情報

アンサイズまわりの挙動の説明のため、専用のトレイトが導入されている。

しかし、、これらはナイトリー版でのみ使える不安定な機能である。そのため、安定版ではこの機能はユーザ定義の型に使えず、組込型の特権となっている。

関連トレイト

Unsized

条件を満たす型にコンパイラが自動で付加する。

以下のような変換を可能にする。

  • [T;n][T]
  • Tdyn U
  • ...
CoerceUnsized

アンサイズ関連の変換に対応したい場合に付加する。

参照先がアンサイズ可能な型なら、参照先のアンサイズに対応する実装が多い。

例えば、組込型 (安定版ではこれが全て) では以下がある。

  • &T
  • &mut T
  • Box<T>
  • Rc<T>
  • Weak<T>
  • Cell<T>
  • RefCell<T>
  • ...

サンプル

以下では、ナイトリー版でのスマートポインタの実装例を示している。
MyPtrCoerceUnsized を実装しているため、参照先を 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.
}