2011-12-22 12 views
22

El atributo en .NET es una característica muy popular. Y Java agregó Anotación después de 1.5 Las anotaciones se usan en todas partes, consulte Java EE y Spring. Pero pocas bibliotecas de scala usan la anotación. lift-json no lo use. lift-record no lo use. Squeryl no lo use. subcut no lo use. (Tiene una anotación para el complemento del compilador) ... Solo mencioné algunos.¿Por qué a las personas scala no les gusta la anotación?

Utilizan la anotación solo cuando necesitan algo de magia del compilador. @tailrec, @inline, @BeanProperty, @Inject (en subcutánea) ...

Scala tiene un sistema de tipo súper flexible, rasgo, implícito y Menifest [X]. ¿Entonces no necesitan metadatos de tiempo de ejecución?

¿Hay alguna anotación de uso del proyecto scala en gran medida?

p.s. Creo que el Dynamic debe ser una anotación pero no un rasgo.

+2

¿Qué problema práctico tiene este lago de uso de anotaciones? – Mat

+0

Dinámico es un tipo. ¿Por qué debería ser una anotación? – Jan

+0

Porque no hay métodos adentro, y cuando lo usa, tiene su propio tipo, Dynamic simplemente le dice que su tipo es dinámico. – iron9light

Respuesta

27

En general, no usamos anotaciones porque realmente no necesitamos para muchas cosas.

los pocos lugares que he visto anotaciones utilizadas:..

  • sistemas de tipo extra (por ejemplo, el plug-in de CPS para continuaciones delimitados o el seguimiento de efectos plug-in
  • Interfaz con interfaces de legado Java (scala-mojo-support)
  • reforzando/permitiendo a las optimizaciones del compilador, como @inline o @tailrec.

En Scala, no lo hacemos realmente necesita un marco de inyección de dependencia, ya que hay algunas formas de do inyección de dependencia que no requieren una herramienta externa. Puede tener la configuración DI separada del código central, pero aún así estar escrita en Scala. Ver: https://github.com/jsuereth/scala-in-depth-source/blob/master/chapter11/src/main/scala/scalax/config/Test.scala

Así que la respuesta básica es que no hay nada de malo con las anotaciones, simplemente no las necesitamos con tanta frecuencia (todavía).

+0

Creo que la anotación para cps, @cpsParam, es un TypeConstraint, más que una anotación tradicional que solo proporciona metadatos en tiempo de ejecución. – iron9light

+0

Es más que Scala es más flexible en lo que se puede anotar que Java/C#. Sigue siendo solo una anotación, usa el mismo AST que otras anotaciones, pero sucede que está en un tipo. Las anotaciones Java también * no * pueden estar disponibles en tiempo de ejecución, pero solo compilar/apt time. Esto se realiza a través de la configuración '@ Retention' en una clase de anotación. – jsuereth

2

Has respondido bastante a tu propia pregunta cuando dijiste que se usaba para compilar magia. Para los demás usos, suele ser algún tipo de magia de tiempo de ejecución, donde las dos herramientas principales son la transformación de código de reflexión y byte.

Para el caso de JSON, las opciones para la conversión sería el siguiente: 1. Una función o clase que analiza su JValue y construye su clase T. 2. La reflexión sobre las clases de objetivos para determinar su disposición y lo es opcional, luego un código "dinámico" que se ejecuta sobre los datos analizados para crear y luego emitir al tipo apropiado.

12

Para mí, a menudo es un problema de seguridad del tipo de compilador. Eche un vistazo a Squeryl y cómo se diferencia de un ORM de Java como Hibernate. Donde Hibernate usaría una anotación @Id para denotar una clave principal, en Squeryl creará un miembro id, que se especifica mediante el rasgo KeyedEntity. Los métodos que requieren una entidad con una clave principal (actualización & eliminar por ejemplo) se bloquean ruidosamente en tiempo de compilación si no se ha definido uno.Hay varios otros lugares dentro de Squeryl donde los constructos de tipo seguro reemplazan las anotaciones, como el mapeo de colecciones y el manejo de fecha/hora.

Creo que esta es una forma común de pensar en la comunidad de Scala. Las anotaciones son más una función de tiempo de ejecución y no están tan bien vistas. El compilador de Scala es muy poderoso y empujar más de tu código a construcciones que valide, tiene sentido para aquellos que están dispuestos a aceptar la complejidad que eso conlleva.

0

Todas las anotaciones como @tailrec y @inline son solo de tiempo de compilación. Extienden StaticAnnotation, que es, AFAIK, el único soporte de anotación en Scala, y no se conservarán en tiempo de ejecución. Creo que la filosofía es evitar las anotaciones en tiempo de ejecución porque se recuperan por reflexión, un mundo donde el compilador ya no puede ayudarlo más allá de las clases estándar debido a borrado de tipo, pero lo más importante es que es runtime y el objetivo es decidir qué estás tratando de decidir en tiempo de compilación.

Mira el uso de anotaciones para modelar una salida JSON, por ejemplo: en Java sabrías si funciona bien cuando ejecutas tu programa. En Scala podría usar clases de tipo para modelar cómo se expresa cada tipo en JSON. Si pierde una definición, la compilación se lo dirá. Un excelente ejemplo es spray-json.

Dave Whittaker da otro gran ejemplo en su answer.

Cuestiones relacionadas