我想了解一下Scala泛型的实现细节。在C#中,可以声明一个类:
class Foo<T1>{}
class Foo<T1, T2>{}
然而,在Scala中,相同的事情必须声明为:
class Foo0[T1]{}
class Foo1[T1, T2]{}
请注意,类名被强制更改以适应多个通用参数。Scala为什么选择这种方式而不是我认为更优雅的C#方式?我知道这可能只是一个小问题,但我对其原因非常好奇。
我想了解一下Scala泛型的实现细节。在C#中,可以声明一个类:
class Foo<T1>{}
class Foo<T1, T2>{}
然而,在Scala中,相同的事情必须声明为:
class Foo0[T1]{}
class Foo1[T1, T2]{}
我知道Jon Skeet的回答已经被接受,但是它并不完全正确。限制的引起者并不是JVM,而是Java语言本身。Scala的设计目标是尽可能地方便从Java中调用,而Java没有基于类型参数数量重载类名的概念。例如,一种在JVM上实现基于类型参数重载的简单方法是使用名称混淆。然而,这种名称混淆必须对Java可见,而且很丑陋。在您的示例中,一个假设的Scala可能会编译出两个类,Foo_$1和Foo_$2。Scala可以使这种混淆不可见。但是,Java程序员会看到所有这些丑陋的细节。
这可能部分是由于Java有相似的限制。据我所知,Scala 主要 用于JVM,而在JVM上,您无法通过重载泛型类型按元数进行重载。
看起来,Scala也使用类型擦除实现其泛型,即使在.NET版本中也是如此。(同一篇文章提到Scala比Java更早支持泛型,因此即使Java也支持此功能,也不能保证Scala会 - 当他们首次设计该功能时,它们受到了某些限制。)
我认为这是为了更容易地映射到Java,因为Java有相同的限制。
虽然可以进行一些名称混淆,但这会使与Java的互操作性变得更加困难。在我看来,他们做出了正确的决定。
{}
。 - Erik Kaplun