为什么不能将& str传递给接受& dyn Display特征对象的函数? [英] Why can a &str not be passed to a function accepting a &dyn Display trait object?

查看:138
本文介绍了为什么不能将& str传递给接受& dyn Display特征对象的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读一本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.

另一种查看方式是,对于strDisplay实现,不存在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");
}

这篇关于为什么不能将&amp; str传递给接受&amp; dyn Display特征对象的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆