【问题标题】:Tell the Rust compiler when two generic types are the same当两个泛型类型相同时告诉 Rust 编译器
【发布时间】:2021-02-18 15:35:33
【问题描述】:

我想知道是否可以告诉 Rust 编译器两个泛型类型是相同的。

在特定情况下,我有一个泛型方法的特征,我想实现一个与字段具有相同泛型类型的结构,如下例所示:

trait Trait {
    fn foo<T>(&self, t: T) -> T;
}

struct Struct<T> {
    t: T
}

impl<T> Trait for Struct<T> {
    fn foo<U>(&self, t: U) {
        self.t
    }
}

Ofc 这里我有一个编译器错误,因为它需要 U 但有一个 T。 我该如何处理这种情况?

移动通用外部 foo 创建 Trait&lt;T&gt; 不是一种选择。

【问题讨论】:

  • 但它们不一定与这样的声明相同! let s = Struct { t: 42 }; func(&amp;s); 和 fn func(s: &amp;dyn Trait) { s.foo("not an integer"); } 必须是合法的。使Trait 泛型或给它一个关联类型是去这里的唯一方法。
  • 这个问题太宽泛,一般无法回答,基本上相当于“我如何在不实现这个特征的情况下实现这个特征?”直截了当的回答是“您不能”,但您几乎可以肯定有比这更具体的需求,如果您更详细地解释问题,我们可能会为您提供帮助。

标签: generics rust


【解决方案1】:

您可能会使用关联类型:

trait Trait {
    type U;
    fn foo(&self, t: Self::U) -> Self::U;
}

struct Struct<T> {
    t: T
}

impl<T: Copy> Trait for Struct<T> {
    type U = T;
    fn foo(&self, t: T) -> T {
        self.t
    }
}

Playground

PS:我添加了一个额外的T: Copy,因为T 需要为Copy 才能返回self.t,因为它是共享参考。

【讨论】:

  • 取决于 OP 对“创建Trait&lt;T&gt; 不是一个选项”的含义,这也可能不合适。但这将是另一种方式。
  • 我认为 OP 不想要Trait&lt;T&gt;,因为它允许单个特征的多个实现。但是,是的,既然你已经指出了,他可能也不想要关联类型。
  • 好吧,OP 还没有说明为什么 OP 不想要 Trait&lt;T&gt;。
【解决方案2】:
fn foo<T>(&self, t: T) -> T;

in a trait 意味着方法必须适用于所有T,并且你的结构字段不可能同时具有所有这些类型!

也就是说,这段代码将根据 trait 和 struct 定义进行编译:

fn main() {
    let x: Struct<i32> = Struct { t: 0 };
    let y: &str = x.foo("abc");
    let z: [i32; 2] = x.foo([0,0]);
}

显然y 和z 不能是x.t。

(写完答案后,我看到 mcarton 的评论中已经说明了这一点;如果他问,我会删除它,但希望这样更清楚一点,不需要dyn)。

【讨论】:

    猜你喜欢
    • 2021-08-16
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多