我想要一个接受各种类型的函数,这些类型可以转换为我的特定类型。在类似的情况下,我会使用std::convert::Into
(或std::convert::From
):
pub struct MyThing;
impl<'a> Into<MyThing> for &'a str {
fn into(self) -> MyThing {
MyThing
}
}
fn main() {}
作为额外的皱纹,在我的具体情况下,转换可能会失败。通常,我会使用Result
来表示可能失败的操作。将这两个概念结合在一起:
pub struct MyThing;
pub struct Error;
impl<'a> Into<Result<MyThing, Error>> for &'a str {
fn into(self) -> Result<MyThing, Error> {
if self.len() % 2 == 0 {
Ok(MyThing)
} else {
Err(Error)
}
}
}
fn main() {}
不幸的是,这似乎违反了一致性规则:
error: the impl does not reference any types defined in this crate;
only traits defined in the current crate can be implemented for
arbitrary types [E0117]
我看到我可以创建自己的特定特征:
struct MyThing;
struct Error;
trait IntoMyThing {
fn into(self) -> Result<MyThing, Error>;
}
impl<'a> IntoMyThing for &'a str {
fn into(self) -> Result<MyThing, Error> {
if self.len() % 2 == 0 {
Ok(MyThing)
} else {
Err(Error)
}
}
}
fn main() {}
甚至更通用的特质:
struct MyThing;
struct Error;
trait MaybeInto<T, E> {
fn into(self) -> Result<T, E>;
}
impl<'a> MaybeInto<MyThing, Error> for &'a str {
fn into(self) -> Result<MyThing, Error> {
if self.len() % 2 == 0 {
Ok(MyThing)
} else {
Err(Error)
}
}
}
fn main() {}
但有没有办法重用标准库中的组件来实现我的目标?
答案 0 :(得分:1)
这是不可能的,因为一致性规则,这使得这样的事情非常不方便,因为你不能这样做,除非你为其中一种类型创建一个新类型,Result
或&str
。有关详细信息,请参阅RFC #1023。
简而言之,根据该RFC规定的新规则,您无法为包不是本地的类型实现非本地包含的特征。
- 修改孤立规则,以便远程特征的impl需要本地类型,该类型是当前包
LT = LocalTypeConstructor<...>
中定义的结构/枚举/特征,或者是对本地类型LT = ... | < | &mut LT
的引用。 / LI> 醇>
因此,由于您未在包中创建Into
特征,也未在Result
类型中创建特征,因此会出现此错误。创建新类型会修复此问题,因为它基本上将非本地类型包装在本地类型中。