Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
860 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 Reply

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...