有没有办法获得特征的类型名称?

时间:2017-06-01 10:34:54

标签: rust

我正在尝试使用std::intrinsics::type_name来获取特征的类型名称但无法编译它:

#![feature(core_intrinsics)]

use std::intrinsics::type_name;

trait TestTrait: Sized {
    fn test(&self);
}

struct MyStruct {}

struct GetType {}

impl GetType {
    fn test_type<T: ?Sized>() {
        let test = unsafe { type_name::<T>() };
        println!("{:?}", test);
    }
}

fn main() {
    GetType::test_type::<i32>();
    GetType::test_type::<MyStruct>();
    GetType::test_type::<TestTrait>();
}

这是我从编译器中得到的错误

error[E0038]: the trait `TestTrait` cannot be made into an object
  --> src/main.rs:23:30
   |
23 |         GetType::test_type::<TestTrait>();
   |                              ^^^^^^^^^ the trait `TestTrait` cannot be made into an object
   |
   = note: the trait cannot require that `Self : Sized`

当我评论第GetType::test_type::<TestTrait>();

时,以下是该测试的输出
"i32"
"MyStruct"

有没有办法解决这个问题或获取特征的类型名称?

感谢@evotopid工作解决方案

#![feature(core_intrinsics)]

use std::intrinsics::type_name;

trait TestTrait { // <--- remove `: Sized` constraint from here 
    fn test(&self);
}

struct MyStruct {}

struct GetType {}

impl GetType {
    fn test_type<T: ?Sized>() { // <--- trick is in that bound
        let test = unsafe { type_name::<T>() };
        println!("{:?}", test);
    }
}

fn main() {
    GetType::test_type::<i32>();
    GetType::test_type::<MyStruct>();
    GetType::test_type::<TestTrait>();
}

导致以下输出

"i32"
"MyStruct"
"TestTrait"

1 个答案:

答案 0 :(得分:3)

实际上这explained in the docs非常好:

  

通常,Self : Sized用于表示特征不应用作特征对象。如果特征来自您自己的箱子,请考虑删除此限制。

如果你想使用我想你想要的特质对象,因为否则获取特征的名称是没有意义的,你必须从你的特征定义中删除Sized约束。

话虽如此,您确定需要内在函数吗?很可能有更好的方法,这也可以让你在将来使用稳定的Rust。