有没有技术上的原因为什么实施不只是impl Foo

有没有技术上的原因为什么实施不只是impl Foo <T>?

问题描述:

我刚才了解到,使用泛型的结构声明为struct Foo<T>,并且实现声明为impl<T> Foo<T>。该book解释下列方式的差异:有没有技术上的原因为什么实施不只是impl Foo <T>?

注意到,我们才能在类型Point<T>使用T只是impl后申报T。在impl之后声明T为普通类型是Rust如何知道Point中的尖括号中的类型是泛型类型而不是具体类型。

再次,我是一个新手,也没有同样的论点具有申报struct<T> Foo<T>(甚至可能fn<T> foo<T>(bar: T))进行?

+1

通过[Rust By Example](https://rustbyexample.com/generics/impl.html),我猜这是因为'impl Foo '已经意味着别的东西:“将Foo泛型类型实现为一个特定类型,称为T“。 – millimoose

+1

想象相反的情况:不'IMPL富'的意思是“为32位整数实现的Foo”或“通用实现美孚的一个'i32'任何类型的参数”?您提到的其他情况中没有这种含糊之处。 – millimoose

+0

@millimoose:所以在某些情况下,''''表示泛型,并且在某种特定类型中?看起来很难知道我在处理哪一个而不熟悉语法。 – l0b0

impl Foo<T> { ... } 

T一个类型参数,或命名T一个实际的类型?如果您回答了第二个问题,那么您已经将泛型抛出窗口:完全不可能为一组通用类型实现功能。如果您的回答第一个,那么你怎么建议用户这样做:

impl Foo<T> { /* generic stuff */ } 
impl Foo<i32> { /* i32-specific stuff */ } 
impl Foo<u32> { /* u32-specific stuff */ } 

这只会是三个impl块,分别命名为Ti32u32类型参数。

你可能会说“很好,只是从上下文决定”。现在,为了弄清楚发生了什么,用户不仅要检查模块的其余部分,还要检查标准库的前奏中的所有导入符号以确定类型是否为参数。 Rust憎恶这种含糊之处。

远,更简单的编译器和读者只是具体什么是和不是一个参数。

您不必这样做与struct,因为括号内的东西不可能是任何东西其他比类型参数声明。

+0

谢谢,这澄清了它。我想我的困惑源于含糊不清,有时*''是指通用的,有时是特定的类型。 – l0b0

除了@dk的回答,我想比较一下Rust如何对Haskell做它。

在Haskell中,所有特定类型必须启动大写。因此,它是非法的写:

data mytype Var = Constructor { 
    myVar :: Var, 
    myInt :: Foo 
} 

相反,哈斯克尔保留其用小写字母开头的类型变量类型:

data MyType var = Constructor { 
    myVar :: var 
    myInt :: Int 
} 

instance MyClass (MyType var) where 
    ... 

这里,var是一个类型变量,MyType是混凝土,并且Int是具体的。

在我看来 - 你可能不会分享,Rust犯了错误,以允许非大写的类型标识符。因此,语言没有别的选择,只能要求你明确地说出哪些类型标识符是变量,哪些是特定的。可以说Rust的明确性提高了可读性。反过来也可以争辩。

锈当然可以增加一个假想的功能,您可能会说:

impl Foo<#T, T, u32> { .. } 

这里,前缀#被认为是指“这是一个类型变量”,所以#T是一个类型变量,T是具体而言,u32是特定的。没有歧义,只需要本地推理。

有了这个功能,你可能会有点少冗长,但我坚信这艘航行了 - 现在加入这个功能,只会增加做同样的事情了非常小的收益的另一种方式。然而,该功能会增加语言用户必须学习的另一个功能的成本。

+1

伟大的比较和问题的总结! – l0b0