2009-06-15 11 views
8

Me pregunto acerca de un detalle de implementación de los genéricos de Scala. En C# se puede declarar una clase como:Genéricos de Scala en comparación con C#

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

en Scala sin embargo, el mismo que tendría que ser declarado como

class Foo0[T1]{} 
class Foo1[T1, T2]{} 

Aviso cómo el nombre de la clase se ve obligado a cambiar para múltiples parámetros genéricos. ¿Hay alguna razón por la cual Scala decidió ir por esta ruta en lugar de la C# que creo que es más elegante? Sé que este es probablemente un pequeño detalle, pero tengo bastante curiosidad sobre el razonamiento.

+0

solo para el registro, esos '{}' no son necesarios en Scala. –

Respuesta

24

Sé que la respuesta de Jon Skeet ha sido aceptada, pero no está del todo bien. No es tanto la JVM lo que fuerza una limitación, ya que es el lenguaje Java. Scala tiene el objetivo de ser tan fácilmente llamable desde Java como sea posible y Java no tiene el concepto de sobrecargar un nombre de clase basado en el parámetro de tipo arity. Por ejemplo, una forma simple de implementar la sobrecarga en función de los parámetros de tipo en la JVM sería con el cambio de nombre. Sin embargo, ese cambio de nombre debería ser visible para Java y sería feo. En su ejemplo, un hipotético Scala podría compilar dos clases, Foo_ $ 1 y Foo_ $ 2. Scala podría hacer ese mangle invisible. Sin embargo, un programador de Java vería toda esa fealdad.

+3

Estoy bastante seguro de que esto es lo que C# hace de todos modos. El nombre del tipo Foo sería Foo'1. –

4

Puede deberse en parte a las restricciones similares de Java. Según tengo entendido, Scala es principalmente utilizado en la JVM, donde no se pueden sobrecargar los tipos genéricos por arity.

Parece que Scala uses type erasure también es genérico, incluso en el puerto .NET. (El mismo artículo menciona que Scala tuvo genéricos mucho antes de Java realmente lo hizo, por lo que incluso si Java hizo apoyo de esto, no hay ninguna garantía de que Scala sería -. Que se limita un poco la primera vez que diseñaron la función)

+0

¿No fue el borrado de tipo simplemente un truco inteligente (más o menos) para evitar chages a la JVM? Si es así, ¿Scala no necesitaría los mismos cambios en la JVM para soportar los genéricos en el tiempo de ejecución? Prefiero pensar que Scala no está mucho mejor que Java en ese sentido. – Joey

+0

Lo haría a menos que agregara algún tipo de información en cada instancia como un campo oculto, o algo así. Ciertamente es muy difícil agregar algo como genéricos "adecuados" a un tiempo de ejecución que no los admite. –

+4

Tenga en cuenta que los genéricos de Scala pueden ser de un tipo superior, a diferencia de .NET. No veo cómo agregarlos a .NET sin borrado. –

2

supongo se hace para mapear más fácilmente a Java, que tiene la misma restricción.

Habría sido posible cambiar el nombre, pero a costa de dificultar la interoperación con Java. En mi opinión, tomaron la decisión correcta.

Cuestiones relacionadas