为什么不能将 &str 传递给接受 &dyn Display trait 对象的函数?

osa*_*amu 7 rust trait-objects

我正在阅读一本 Rust 书,但我对这个例子感到困惑:

use std::fmt::Display;

fn main() {
    test("hello");
    test2("hello")
}

fn test(s: &dyn Display) {
    println!("{}", s);
}

fn test2(s: &str) {
    println!("{}", s);
}
Run Code Online (Sandbox Code Playgroud)

&'static str作为特征对象传递失败:

use std::fmt::Display;

fn main() {
    test("hello");
    test2("hello")
}

fn test(s: &dyn Display) {
    println!("{}", s);
}

fn test2(s: &str) {
    println!("{}", s);
}
Run Code Online (Sandbox Code Playgroud)

为什么这会失败而第二次调用有效?

tre*_*tcl 10

str确实实现了Display,但不可能将 a 强制转换&str为 a,&dyn Display因为Displayfor的实现str可能(并且确实)使用字符串的长度。Length 是 type 的一部分,&str但不是type 的一部分&dyn Display,您不能丢弃长度,因为这将使其根本无法实现Display

另一种方式来看待,这是一个虚函数表(虚拟方法表)不存在实施Displaystr,因为虚函数表可能只包含接受薄功能self指针,但impl Display for str&self是脂肪指针。另请参阅为什么不能将 `&(?Sized + Trait)` 转换为 `&dyn Trait`?

但是,&str它本身也实现了Display,因此您可以test通过简单地添加另一层间接来完成工作:

fn main() {
    test(&"hello");
}
Run Code Online (Sandbox Code Playgroud)