为什么不能将& str传递给接受& dyn Display特征对象的函数? [英] Why can a &str not be passed to a function accepting a &dyn Display trait object?
问题描述
我正在阅读一本Rust书,这个例子让我感到困惑:
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);
}
将&'static str
作为特征对象传递失败:
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?
推荐答案
str
确实实现了Display
,但是由于将Display
的实现用于str
可以(并且确实)使用字符串的长度.长度是类型&str
的一部分,而不是类型&dyn Display
的一部分,并且您不能舍弃该长度,因为它根本不可能实现Display
.
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.
另一种查看方式是,对于str
的Display
实现,不存在vtable(虚拟方法表),因为vtable可能只包含接受瘦self
指针的函数,而在impl Display for str
,&self
是粗大指针.另请参见为什么不能&&(?Sized + Trait )`转换为`& dyn Trait`?
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`?
但是,&str
本身也实现了Display
,因此您可以通过简单地添加另一层间接寻址来使test
工作:
However, &str
itself also implements Display
, so you can make test
work by simply adding another layer of indirection:
fn main() {
test(&"hello");
}
这篇关于为什么不能将& str传递给接受& dyn Display特征对象的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!