为"从"的两个步骤制作通用的"从"/"到"快捷方式



StructA实现From<StructB>StructB实现From<S>

如何通用地实现"快捷方式"Into<StructA> for SFrom<S> for StructA

如果这是个坏主意,请告诉我。但为了学习,请解释一下如何做

这是我的尝试:

struct StructA {
f: StructB
}
struct StructB {
g: i32
}
impl From<StructB> for StructA {
fn from(v: StructB) -> Self {
Self {
f: v
}
}
}
impl From<i32> for StructB {
fn from(v: i32) -> Self {
Self {
g: v
}
}
}
impl<T: Into<StructA>, S: Into<T>> Into<StructA> for S {
fn into(self) -> StructA {
let i: T = self.into();
i.into()
}
}

我得到的错误是the type parameter 'T' is not constrained by the impl trait, self type, or predicates

我不明白。T不是受Into<StructA>的约束吗?

错误消息基本上说明编译器无法推断T可能是什么类型——它基本上必须弄清楚是否存在任何类型的T,以便满足给定的特征边界T: Into<StructA>, S: Into<T>,而这在Rust中是不可能的。正如评论中所说,这样做的一个问题是,可能有多个类型T满足特征边界,在这种情况下,编译器无法确定使用哪一个。

此外,Into特性已经在标准库中进行了一揽子实现。

impl<T, U: From<T>> Into<U> for T;

编译器无法保证这个impl不会与您的一揽子impl重叠,这也会使实现变得不明确。

我建议您只需显式地实现From<i32> for StructA。如果您需要许多这样的实现,宏可能会很有用。

没有办法产生一个完全通用的解决方案,因为即使你使它通过了"无约束类型参数";您将遇到的错误;冲突特征实现";错误。这是我所能得到的最接近的结果,它允许将StructB转换为StructA将任何类型的StructB转换为StructA:

#[derive(Eq, PartialEq, Debug)]
struct StructA {
f: StructB
}
#[derive(Eq, PartialEq, Debug)]
struct StructB {
g: i32
}
impl From<i32> for StructB {
fn from(v: i32) -> Self {
Self {
g: v
}
}
}
impl<T> From<T> for StructA
where
T: Into<StructB>
{
fn from(t: T) -> StructA {
let structb = t.into();
StructA {
f: structb
}
}
}
fn main() {
let a1: StructA = StructB { g: 12 }.into();
let a2: StructA = 12.into();
assert_eq!(a1, a2);
}

操场

据我所知,这在稳定的Rust上是不可能的,因为它需要某种形式的专业化。让我们考虑一下这个代码:

// "StructB -> StructA"
impl From<StructB> for StructA {
fn from(v: StructB) -> Self {
Self { f: v }
}
}
impl From<i32> for StructB {
fn from(v: i32) -> Self {
Self { g: v }
}
}
// "shortcut"
impl<T> From<T> for StructA
where
StructB: From<T>,
{
fn from(t: T) -> Self {
Self::from(StructB::from(t))
}
}

编译器将抱怨"StructB -> StructA"impl与"shortcut"impl冲突。这是真的,因为From<T>本身有一个一揽子实现。

现在使用Into根本没有帮助,因为Into是自反的。所以即使你克服了";不受约束";错误,您将返回到冲突的实现。

然而夜间有可能。通过使用自动特征的一点技巧(这里有一篇关于它的好文章),我们可以限制";快捷方式";实现仅覆盖不同于CCD_ 25的类型。

游乐场连接

相关内容

  • 没有找到相关文章

最新更新