Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics Scala泛型与C语言的比较#_Generics_Scala_Overloading - Fatal编程技术网

Generics Scala泛型与C语言的比较#

Generics Scala泛型与C语言的比较#,generics,scala,overloading,Generics,Scala,Overloading,我只是想知道Scala泛型的实现细节。在C#中,可以将类声明为: class Foo<T1>{} class Foo<T1, T2>{} 请注意,如何强制更改多个泛型参数的类名。Scala决定走这条路线,而不是我觉得更优雅的C#路线,有什么原因吗?我知道这可能是一个很小的吹毛求疵,但我对其原因很好奇。这很可能部分是由于Java的类似限制。据我所知,Scala主要用于JVM,在JVM中不能通过算术重载泛型类型 它的泛型看起来也一样,即使在.NET端口中也是如此。(同一篇文

我只是想知道Scala泛型的实现细节。在C#中,可以将类声明为:

class Foo<T1>{}
class Foo<T1, T2>{}

请注意,如何强制更改多个泛型参数的类名。Scala决定走这条路线,而不是我觉得更优雅的C#路线,有什么原因吗?我知道这可能是一个很小的吹毛求疵,但我对其原因很好奇。

这很可能部分是由于Java的类似限制。据我所知,Scala主要用于JVM,在JVM中不能通过算术重载泛型类型


它的泛型看起来也一样,即使在.NET端口中也是如此。(同一篇文章提到Scala早在Java真正支持泛型之前就已经有了泛型,所以即使Java确实支持它,也不能保证Scala会支持泛型——它们在最初设计该功能时受到了一定的限制。)

我想这样做是为了更容易地映射到Java,Java也有同样的限制


本来可以进行一些名称篡改,但代价是使与Java的互操作更加困难。在我看来,他们做出了正确的决定。

我知道乔恩·斯基特的回答已经被接受,但并不完全正确。与其说JVM有限制,不如说它是Java语言。Scala的设计目标是尽可能容易地从Java调用,Java没有基于类型参数arity重载类名的概念。例如,在JVM上实现基于类型参数的重载的一种简单方法是名称混乱。然而,这个名称的混乱必须对Java可见,而且是丑陋的。在您的示例中,一个假设的Scala可能编译两个类,Foo_u$1和Foo_$2。Scala可以让你看不见那些碎片。然而,Java程序员会看到所有这些丑陋之处。

类型擦除不只是一种聪明(或多或少)的黑客,以避免对JVM造成影响吗?如果是这样的话,Scala难道不需要对JVM进行同样的更改以在运行时支持泛型吗?我宁愿认为Scala在这方面并不比Java好多少,除非它在每个实例中添加一些类型信息作为隐藏字段或类似的内容。在不支持“适当”泛型的运行库中添加类似“适当”泛型的东西当然是非常困难的。请注意,Scala泛型可以是更高级的,不像.NET。我不知道如何在不删除的情况下将它们添加到.NET中。@alexey\u r:这很公平——我不知道Scala是否足够。有可能在更高级泛型泛型中使用擦除,但对于“简单”泛型没有擦除吗?当然,您可以通过创建自己的类名- Mangle方案(与C++在函数/方法类型和属性上的重载非常相似),创建基于JVM上的类型参数的重载的语言。但这将否定Java集成曾经的重要领域。此外,鉴于大多数ML派生和Haskell的实现都会在运行时擦除所有类型,我不认为擦除是“不恰当的”。我很确定C#就是这么做的。Foo的类型名应该是Foo`1。就记录而言,Scala中不需要那些
{}
class Foo0[T1]{}
class Foo1[T1, T2]{}