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

3

在尝试使用带有泛型参数的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;
    }
}

(游乐场)

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

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

在这个上下文中,这似乎没有什么意义。我猜这可能是我对通用特征的误用,但错误信息让问题变得更加模糊。

1个回答

5
在方法实现的上下文中,Settings 是一个“通用类型”(generic type)。
也就是说,在你的示例中,你拥有的东西相当于这个:
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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接