Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
857 views
in Technique[技术] by (71.8m points)

rust - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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");
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...