2016-12-22 52 views
2

在嘗試實現具有泛型參數的特徵並訪問這些泛型參數的字段時,我遇到了一條錯誤消息,說明所討論的參數不包含這些字段。無法訪問動態特徵實現中的結構字段

下面是顯示該問題的一些示例代碼:

pub struct Settings { 
    pub time: String, 
} 

pub trait Foo { 
    fn get<T>(t: T); 
} 

struct Bar; 

impl Foo for Bar { 
    fn get<Settings>(t: Settings) { 
     let x = t.time; 
    } 
} 

Playground

由編譯器給定的錯誤信息是如下:

error: no field `time` on type `Settings` 

這沒有什麼意義在上下文。我認爲這可能是我的一些濫用通用特徵的錯誤信息,但這個問題使得這個問題成爲現實。

回答

4

在方法實現的上下文中,Settings是「通用類型」。

也就是說,你已經在你的榜樣了那裏,就是這相當於:

impl Foo for Bar { 
    fn get<RandomWordHere>(t: RandomWordHere) { 
     let x = t.time; 
    } 
} 

是否錯誤更有意義呢?您的通用類型Settings遮蔽了您的實際類型Settings

現在無論如何,你的方法在這個意義上不是非常通用的..既然你說「我想要一個Settings結構的實際實例」。而您可能想要「我想要一個具有time字段的任何類型的實例」。

這裏是你怎麼做後者:

pub trait HasTime { 
    fn get_time(&self) -> &String; 
} 

pub struct Settings { 
    pub time: String 
} 

impl HasTime for Settings { 
    fn get_time(&self) -> &String { 
     &self.time 
    } 
} 

pub struct OtherStruct; 

pub trait Foo { 
    fn get<T>(t: T) where T: HasTime; 
} 

struct Bar; 

impl Foo for Bar { 
    fn get<T>(t: T) where T: HasTime { 
     let x = t.get_time(); 
    } 
} 

fn main() { 
    Bar::get(Settings{time: "".into()}); // This is fine 
    // Bar::get(OtherStruct{}); // This is an error.. it doesn't implement HasTime 
} 

Playground link