【问题标题】:"conflicting implementations for trait" when trying to be generic尝试通用时“冲突的特征实现”
【发布时间】:2017-09-11 03:10:46
【问题描述】:

背景:我正在使用nalgebra 库,我想创建一个表示多元正态分布的结构。 M 是矩阵的类型,例如Mat4<f64>.

我目前的尝试是这样的:

use std::ops::Mul;
use std::marker::PhantomData;
use nalgebra::*;

#[allow(non_snake_case)]
pub struct Multivar????<N, V, M: SquareMat<N, V>> {
    μ: V,
    Σ: M,
    marker: PhantomData<N>
}

impl<N, V, M> Mul<Multivar????<N, V, M>> for M {
    type Output = Multivar????<N, V, M>;
    fn mul(self, rhs: Multivar????<N, V, M>) -> Multivar????<N, V, M> {
        Multivar???? {
            μ: self * rhs.μ,
            Σ: self * rhs.Σ * transpose(&self)
        }
    }
}

但是,编译器抱怨:

error: type parameter `M` must be used as the type parameter for some local type (e.g. `MyStruct&lt;T&gt;`); only traits defined in the current crate can be implemented for a type parameter

error: conflicting implementations for trait `core::ops::Mul`

我不认为这应该是一个错误,因为我正在为我在此模块中定义的结构定义一个实现。我应该如何解决这个问题?

【问题讨论】:

  • SquareMat 是否为 NV 提供类型,所以您可以制作类似:pub struct Multivar????&lt;M: SquareMat&lt;N, V&gt;&gt; { μ: M::V, Σ: M, marker: PhantomData&lt;M::N&gt; }
  • 请提供minimal compilable and verifiable example,最重要的是您的代码缺少SquareMat 特征,并且您的错误消息引用了无处显示的MyStruct 类型。对于 Rust 问题,如果您的错误在 play.rust-lang.orgplay.rust-lang.org
  • 请同时查看两个错误的现有问题(12)并向我们解释为什么您的问题不同。否则,您可能会被标记为重复、已关闭或得到无用的答案。

标签: types rust


【解决方案1】:

您的代码的问题在于您的代码存在一致性违规,并且很可能任何修复它的尝试都会导致新的一致性违规。

Rust 中的一致性规则有些复杂,但是它们基于一个原则:您可以为任意类型实现“您的”特征,也可以为“您的”类型实现任意特征。这听起来很简单,但是当类型参数出现时,它就变得复杂了——事实证明,有不止一种方法可以定义哪些类型是“你的”,哪些不是。

在这种特殊情况下,错误在于您直接为类型参数实现了外部特征:

impl<N, V, M> Mul<Multivar?<N, V, M>> for M

这直接违反了上述原则——你不能为你不拥有的类型实现你不拥有的特征(这样的实现被称为“孤儿实现”)。这正是您的第一个错误。

第二个错误让我认为您的Mul 实现比您在此处提供的要多;无论如何,这也是违反连贯性的。通常,当您有适用于特征的两个或多个不同实现的类型集的交集时,会导致此类错误:

use std::fmt;

trait X {}

impl X for i32 {}
impl<T: fmt::Display> X for T {}

这里的实现是冲突的,因为它们都适用于i32,因为i32 实现了fmt::Display

其实很难说出自己想要什么,所以也很难给出满意的答案。我试图解释上面这些错误的原因,希望它能帮助你正确地编写 trait 实现。如果您有兴趣,可以在this 博客文章中找到更多关于孤儿规则的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多