Consider the following code:
trait Tr {
fn to_str(&self) -> &str;
}
struct Data;
impl Tr for Data {
fn to_str(&self) -> &str {
"Data"
}
}
struct Obj<T: ?Sized> {
val: T
}
fn foo(o: &Obj<dyn Tr>) {
println!("output = {:?}", o.val.to_str());
}
fn main() {
let d = Data;
let o = Obj { val: d };
foo(&o);
}
&Obj<dyn Tr>
is not a trait object because it's not a pointer to a trait, at least not exactly. But it looks like Data
's vtable for Foo
is part of the pointer (and not Obj
's layout) because mem::size_of::<&Obj<dyn Tr>>() == 16
on my system.
I haven't seen any mention of this type of object in the book, and the definition of "trait object" doesn't seem to include it. Should this be covered somehow? Should it have its own name or stretch "trait object" to be more inclusive. Could a unified nomenclature encompass pointers to other unsized or dynamically sized types, like &[u8]
or &str
, or are these different because they don't require a vtable (although they may require size information instead)?