【问题标题】:Rust complains about generic argument not satisfying trait bound even though it is not required [duplicate]Rust 抱怨通用参数不满足 trait bound,即使它不是必需的 [重复]
【发布时间】:2020-05-05 17:35:39
【问题描述】:

我正在尝试编译以下 rust 代码:

#[derive(Clone)]
struct Foo<Data> {
    f: fn(&Data),
}

trait Trait : Clone {
    type DataType;
}

// throws:
// error[E0277]: the trait bound `Data: std::clone::Clone` is not satisfied
impl<Data> Trait for Foo<Data> {
    type DataType = Data;
}

它抱怨 Data 通用参数不满足 Clone 约束,即使它不应该满足。

据我了解Foo&lt;Data&gt; 应该支持Clone 而无需Data 支持。

我做错了什么?

【问题讨论】:

    标签: rust traits


    【解决方案1】:

    Clonederive 有时会添加限制性的 where 约束。截至 2020 年 5 月,它仍然是一个开放的错误。请参阅:#[derive] sometimes uses incorrect bounds · Issue #26925 · rust-lang/rust

    解决方法是为此结构手动实现Clone。例如:

    impl<Data> Clone for Foo<Data> {
        fn clone(&self) -> Self {
            Self { f: self.f }
        }
    }
    

    【讨论】:

    • 非常感谢。不过,这有点奇怪。只有当我添加impl Trait 时才会出现问题。没有它派生成功就好了。您是否知道任何不需要手动克隆的解决方法?
    • 派生的 impl 有 where Data: Clone,这本身是可以的(尽管在这种特定情况下它是 derive 问题)。现在理解这一点很重要,Foo&lt;Data&gt;: Clone 不成立,除非Data : Clone 也成立。到现在为止还挺好。现在是 trait 和 impl。因为我们有Trait : Clone,那么impl 需要Foo&lt;Data&gt;: Clone,因此需要Data: Clone。但是,impl 不限制为Data: Clone,因此失败。
    • 为什么它没有在结构定义上立即失败?因为数据也不受限制。
    • 结构定义本身没有任何东西需要来自DataClone,因此它仍然有效。比如说,如果你有一个没有实现Clonestruct Bar {},你可以声明let x : Foo&lt;Bar&gt; = Foo { f: |_| {} };,它会编译。但是,如果您尝试添加 let y = x.clone();,它将无法构建,因为 Foo&lt;Bar&gt;: Clone 不成立。
    • 啊,我明白了。我觉得我懂了。仅当所有成员都支持克隆时,派生才会添加实现。我的印象是它是无条件的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2021-12-04
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多