Rust-AnyTrait

  1. 一、介绍
  2. 二、例子

一、介绍

实现了Any trait,它可以'static通过运行时反射实现任何类型的动态类型。

pub trait Any: 'static + Reflect {
fn get_type_id(&self) -> TypeId;
}

Any在定义的时候就规定了其生命周期,而Reflect是一个Marker,默认所有的Rust类型都会实现他!注意,这里不是所有原生类型,而是所有类型。

  1. Any本身可以用来获取TypeId, 并且作为 trait 对象使用时具有更多的特性。
  2. 作为&dyn Any(借用的 trait 对象),它具有is 和downcast_ref方法,用于测试包含的值是否属于给定类型,并获取对内部值作为类型的引用。
  3. 作为&mut dyn Any,还有downcast_mut一种方法,用于获取对内部值的可变引用。
  4. Box<dyn Any>添加downcast方法,该方法尝试转换为Box<T>

二、例子

我们在编译时不知道我们的值的具体类型,所以我们需要使用运行时反射来代替。

use std::fmt::Debug;
use std::any::Any;

// Logger function for any type that implements Debug.
fn log<T: Any + Debug>(value: &T) {
let value_any = value as &dyn Any;

// Try to convert our value to a `String`. If successful, we want to
// output the String`'s length as well as its value. If not, it's a
// different type: just print it out unadorned.
match value_any.downcast_ref::<String>() {
Some(as_string) => {
println!("String ({}): {}", as_string.len(), as_string);
}
None => {
println!("{:?}", value);
}
}
}

// This function wants to log its parameter out prior to doing work with it.
fn do_work<T: Any + Debug>(value: &T) {
log(value);
// ...do some other work
}

fn main() {
let my_string = "Hello World".to_string();
do_work(&my_string);

let my_i8: i8 = 100;
do_work(&my_i8);
}

看到 do_work函数中的泛型T。要求其实现AnyDebug。通过value as &Any;我们需要将传入的类型转化成一个 trait Object。

这样,value 就可以被堪称一个 Any 了。然后,我们通过 downcast_ref 来进行类型推断。如果类型推断成功,则 value 就会被转换成原来的类型。