Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can a &str not be passed to a function accepting a &dyn Display trait object?

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?

like image 907
osamu Avatar asked Sep 06 '19 07:09

osamu


People also ask

Why can a pace or a footstep?

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.

Why doesn't a bird get a shock when it stands on a high voltage wire?

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.

Why can't birds fly in a vacuum?

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.

Why we Cannot use a pace or a footstep as a standard unit of length?

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.


1 Answers

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");
}
like image 63
trent Avatar answered Sep 19 '22 06:09

trent