2017-06-01 112 views
2

我試圖用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" 

回答

3

這實際上是explained in the docs相當不錯:

一般來說,Self : Sized使用以表明該性狀不應該被用作特徵對象。如果特質來自你自己的箱子,考慮取消這個限制。

如果你想使用特質的對象,我想你想要的,因爲否則就沒有意義獲得性狀的名字,你必須從你的特徵定義刪除Sized約束。

這就是說,你確定你需要內在?最有可能的是有一個更好的方法,這也可以讓你在將來使用穩定的Rust。

+0

感謝您的回答@evotopid。如果我刪除'Sized'約束,我仍然無法獲得'GetType :: test_type :: ();'來編譯(請參閱我的更新後的編譯錯誤消息)。 解決此問題的唯一方法是調用'GetType :: test_type :: >();'這非常麻煩(我仍然可以解析字符串以獲得我想要的內容,但調用有點奇怪) 我想獲取特徵名稱作爲字符串,然後在地圖中使用,而不是作爲特徵對象。我閱讀了關於內在函數的警告,但找不到另一種方式來獲得這個 – Boris

+0

這似乎是工作? https://play.rust-lang.org/?gist=8b8220dc22bfb9ffc070ac9c6748d38e&version=nightly&backtrace=0 – evotopid

+0

事實上,我需要在'test_type()'函數中添加''約束。非常好,謝謝 (編輯我原來的問題給讀者) – Boris

相關問題