トレイトオブジェクトになれないトレイト

Using Trait Objects That Allow for Values of Different Types - The Rust Programming Language

以下のメソッドを含むトレイトは、トレイトオブジェクトになれない (オブジェクトセーフではないため)

Note:

Swiftでも型として宣言できるプロトコルと宣言できないプロトコルがある

  • 型として宣言できるプロトコル: Self、関連型を持たない
  • 型として宣言できないプロトコル: Self、関連型を持つ

Self を返す

CloneトレイとはSelfを返すメソッドを持つため、トレイトオブジェクトには出来ない。

pub trait Clone {
    fn clone(&self) -> Self;
}
pub struct Screen {
    pub components: Vec<Box<dyn Clone>>,
}

   Compiling gui v0.1.0 (file:///projects/gui)
error[E0038]: the trait `Clone` cannot be made into an object
 --> src/lib.rs:2:21
  |
2 |     pub components: Vec<Box<dyn Clone>>,
  |                     ^^^^^^^^^^^^^^^^^^^ the trait `Clone` cannot be made into an object
  |
  = note: the trait cannot be made into an object because it requires `Self: Sized`

ジェネリクス

generics - Unable to create a polymorphic type because the trait cannot be made into an object - Stack Overflow

use std::io::Result;

pub trait PacketBuffer {}

pub trait DnsRecordData {
    fn write<T: PacketBuffer>(&self, buffer: &mut T) -> Result<usize>;
}

pub struct DnsRecord<R: DnsRecordData + ?Sized> {
    pub data: Box<R>,
}

pub struct DnsPacket {
    pub answers: Vec<DnsRecord<dyn DnsRecordData>>,
}

/*
error[E0038]: the trait `DnsRecordData` cannot be made into an object
  --> src/lib.rs:14:5
   |
14 |     pub answers: Vec<DnsRecord<dyn DnsRecordData>>,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `DnsRecordData` cannot be made into an object
   |
   = note: method `write` has generic type parameters
*/

DnsRecordData が、ジェネリック型パラメーターを持つ関数があるために、トレイトオブジェクトにすることができない。