I'm reading a Rust book and I am confused by this example:
use std::fmt::Display;
fn main() {
test("hello");
test2("hello")
}
fn test(s: &dyn Display) {
println!("{}", s);
}
fn test2(s: &str) {
println!("{}", s);
}
Passing &'static str
as a trait object fails:
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> src/main.rs:4:10
|
4 | test("hello");
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `str`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required for the cast to the object type `dyn std::fmt::Display`
Why does this fail and the second call work?
Pace or a footstep cannot be used as a standard unit of length because the length of a footstep, forearm length, and hand span may vary from person to person.
Birds sitting on a wire don't touch the ground (or anything in contact with the ground), so electricity stays in the power line. But, if a bird touches a power line and equipment or other metal that is grounded, it gives electricity a path to the ground, and the bird could be shocked.
Without air, like in a vacuum, it is not possible to generate low and high pressure around a wing and so the bird cannot achieve lift.
The size of the foot varies from person to person. If footsteps of two persons are used to measure the length respectively, then the two distances may not be equal. Thus, a footstep is not a constant quantity. Hence, it cannot be used as a standard unit of length.
str
does implement Display
, but it is not possible to coerce a &str
to a &dyn Display
because the implementation of Display
for str
may (and does) use the string's length. Length is part of the type &str
but not part of the type &dyn Display
, and you can't discard the length because that would make it impossible to implement Display
at all.
Another way to look at this is that a vtable (virtual method table) does not exist for the implementation of Display
for str
, because vtables may only contain functions that accept thin self
pointers, but in impl Display for str
, &self
is a fat pointer. See also Why can't `&(?Sized + Trait)` be cast to `&dyn Trait`?
However, &str
itself also implements Display
, so you can make test
work by simply adding another layer of indirection:
fn main() {
test(&"hello");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With