为什么下面的注释掉的bar
代码没有编译,即使foo
和baz
也这样做了?
use std::any::Any;
use std::fmt::Display;
// `value` implements `Clone`, so I can call `.clone()`.
fn foo<T: Display + Clone>(value: &T) {
println!("{}", value.clone());
}
// `value` implements `Any`, so I should be able to call `.downcast_ref`...
// But this doesn't compile!
//
// fn bar<T: Display + Any>(value: &T) {
// println!("{}", value.downcast_ref::<i32>());
// }
// For some reason I have to do an explicit cast to `&Any`...
fn baz<T: Display + Any>(value: &T) {
let value = value as &Any;
println!("{}", value.downcast_ref::<i32>().unwrap());
}
fn main() {
foo(&7);
// bar(&8);
baz(&9);
}
尝试编译bar
会产生以下编译器错误:
error[E0599]: no method named `downcast_ref` found for type `&T` in the current scope
--> src/main.rs:13:30
|
13 | println!("{}", value.downcast_ref::<i32>());
| ^^^^^^^^^^^^
我已经详细说明了value
必须实施Any
的约束,那为什么我必须做一个明确的演员?
答案 0 :(得分:9)
那是因为downcast_ref
不是特质本身的一部分。如果我们查看特征的定义in the documentation:
pub trait Any: 'static {
fn get_type_id(&self) -> TypeId;
}
我们可以看到downcast_ref
不存在。只有定义为特征成员的方法才能在实现该特征的类型上使用。
相反,downcast_ref
位于impl Any + 'static
块 1 中。由于该方法采用&self
,因此该方法仅适用于&(Any + 'static)
类型的值(&Any
,未指定生命周期等同于&(Any + 'static)
)。 &Any
和&T
(其中T
是类型参数)不是同一类型; &Any
是一个特征对象(它是一个胖指针),而&T
只是一个普通的引用(它是一个瘦指针)。
1 它也在impl Any + 'static + Send
块中定义,因此该方法也适用于&(Any + 'static + Send)
类型的值。