为什么Rust在“impl”关键字之后需要泛型类型声明?

33

定义泛型类型的方法需要在impl后添加泛型类型:

struct GenericVal<T>(T,);
impl <T> GenericVal<T> {}

我认为移除<T>是可以的:
struct GenericVal<T>(T,);
impl GenericVal<T> {}

有没有特别的考虑?

3
对于其他有同样疑问的人,请查看我的文章 这里,我尝试用简单的示例解释为什么需要这样做。 - John
1个回答

46

Rust允许你编写仅适用于某些特定类型参数组合的impl块。例如:

struct GenericVal<T>(T);

impl GenericVal<u32> {
    fn foo(&self) {
        // method foo() is only defined when T = u32
    }
}

这里,类型GenericVal是泛型的,但是impl本身不是泛型的。
因此,如果您想编写一个适用于所有GenericVal<T>类型的impl块,您必须首先在impl本身上声明一个类型参数(否则,T将尝试查找名为T的类型)。
struct GenericVal<T>(T);

impl<T> GenericVal<T> {
    fn foo(&self) {
        // method foo() is always present
    }
}

这个声明还允许您拥有一个可以多次使用的单个类型参数,强制类型相同。

struct GenericVal<T, U>(T, U);

impl<V> GenericVal<V, V> {
    fn foo(&self) {
        // method foo() is only defined when T = U
    }
}

1
然而,似乎编译器可以从 GenericVal 的类型参数中推断出而不是 impl。你能解释一下为什么 impl<V> 语法是必须的吗? - yeshengm
我不认为这是严格必要的,但如果有助于防止歧义,那就好了。如果有人在该模块的范围内引入了一个名为 V 的类型,那怎么办?impl 中使用的 V 是指具体类型 V(例如我的答案中的第一个示例)还是隐式泛型参数 V - Francis Gagné
正如Francis所说,impl可以用于实现特定类型,你可以将签名impl<T> GenericVal<T> {}看作是一个声明,而GenericVal<T>是该声明类型的使用。 - Akshay Naik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接