什么算作冲突的实施?

Sam*_*kwu 5 rust

在下面的代码中:

enum Either<A, B> { Left(A), Right(B) }

use Either::{Left, Right};

impl<A, B> From<A> for Either<A, B> {
    fn from(a: A) -> Self {
        Left(a)
    }
}

impl<A, B> From<B> for Either<A, B> {
    fn from(b: B) -> Self {
        Right(b)
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:“std::convert::From<_>类型特征的实现冲突Either<_, _>”。From<A>我不明白和From<B>for的实现Either<A, B>是如何冲突的。

我在标准库文档中看到了一个示例,其中他们所做的几乎与我正在做的完全一样,但它在那里工作:

use std::fs;
use std::io;
use std::num;

enum CliError {
    IoError(io::Error),
    ParseError(num::ParseIntError),
}

impl From<io::Error> for CliError {
    fn from(error: io::Error) -> Self {
        CliError::IoError(error)
    }
}

impl From<num::ParseIntError> for CliError {
    fn from(error: num::ParseIntError) -> Self {
        CliError::ParseError(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

请问有人可以解释一下吗?谢谢。

Cas*_*sie 0

在你的原始代码中:

enum Either<A, B> { Left(A), Right(B) }

use Either::{Left, Right};

impl<A, B> From<A> for Either<A, B> {
    fn from(a: A) -> Self {
        Left(a)
    }
}

impl<A, B> From<B> for Either<A, B> {
    fn from(b: B) -> Self {
        Right(b)
    }
}
Run Code Online (Sandbox Code Playgroud)

您为 Either<A, B> 实现 From 特征两次,因为 From 受相同特征 A 和 B 的约束。这可能会导致您出现多次实现 From 的问题。我无法确认这一点,因为该问题无法从提供的代码中重现。直接使用提供的代码会引发错误,指出 A 和 B 未定义。

将原始代码和功能代码结合在一起;我们可以为类型提供定义。但是,由于边界不正确,以下代码仍然会失败。在这种情况下,特征边界由结构约束:

use std::{io, num};

enum Either<A, B> { Left(A), Right(B) }

use Either::{Left, Right};

impl<A: io::Error, B: num::ParseIntError> From<A> for Either<A, B> {
    fn from(a: A) -> Self {
        Left(a)
    }
}

impl<A: io::Error, B: num::ParseIntError> From<B> for Either<A, B> {
    fn from(b: B) -> Self {
        Right(b)
    }
}
Run Code Online (Sandbox Code Playgroud)

会导致如下错误:

error[E0404]: expected trait, found struct `num::ParseIntError`
Run Code Online (Sandbox Code Playgroud)

要制作功能版本,应删除特征边界。生成类似以下内容的内容,编译时不会出现错误:

use std::{io, num};

enum Either<A, B> { Left(A), Right(B) }

type A = io::Error;
type B = num::ParseIntError;

use Either::{Left, Right};

impl From<A> for Either<A, B> {
    fn from(a: A) -> Self {
        Left(a)
    }
}

impl From<B> for Either<A, B> {
    fn from(b: B) -> Self {
        Right(b)
    }
}
Run Code Online (Sandbox Code Playgroud)

From 只能在其实现的类型参数上使用,并且不需要特征边界。

您可以在此处找到有关特征边界的更多信息:https ://doc.rust-lang.org/reference/trait-bounds.html

您可以在此处找到有关类型参数的更多信息:https ://doc.rust-lang.org/reference/types/parameters.html

您可以在此处找到 From 特征的文档: https: //doc.rust-lang.org/std/convert/trait.From.html