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

时间:2016-12-22 04:28:12

标签: generics rust traits

在尝试使用泛型参数实现traits并访问这些泛型参数的字段时,我遇到了一条错误消息,指出有问题的参数不包含这些字段。

以下是展示问题的示例代码:

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`

在上下文中没什么意义。我希望这可能是我对通用特性的一些滥用,但错误信息提出了这个问题。

1 个答案:

答案 0 :(得分: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