无法访问动态特征实现中的结构字段

Ame*_*meo 3 generics traits rust

在尝试使用通用参数实现特征并访问这些通用参数的字段时,我遇到一条错误消息,指出相关参数不包含此类字段。

下面是一些显示该问题的示例代码:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

游乐场

编译器给出的错误信息如下:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这在上下文中没有什么意义。我预计这可能是我对通用特征的一些误用,但错误消息提出了这样的问题。

Sim*_*ead 5

在方法实现的上下文中,Settings是“通用类型”。

也就是说,您在示例中得到的内容相当于:

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

现在这个错误更有意义了吗?您的泛型类型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
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接