2012-09-10 5 views
10

En Scala, si tenemos¿Automáticamente crea getters para los parámetros de clase (para evitar clases de casos)?

class Foo(bar:String) 

podemos crear un nuevo objeto, pero no puede acceder a bar

val foo = new Foo("Hello") 
foo.bar // gives error 

Sin embargo, si declaramos Foo ser un case class esto funciona:

case class Foo(bar:String) 
val foo = Foo("hello") 
foo.bar // works 

Estoy obligado a hacer muchas de mis clases como clases de casos debido a esto. De lo contrario, tengo que escribir código repetitivo para acceder bar:

class Foo(bar:String) { 
    val getbar = bar 
} 

Así que mis preguntas son:

  1. ¿Hay alguna manera de "arreglar" esto sin usar las clases de casos o código repetitivo?
  2. ¿Está utilizando clases de casos en este contexto una buena idea? (o ¿cuáles son las desventajas de las clases de casos?)

Supongo que el segundo merece una pregunta por separado.

Respuesta

17

sólo tiene que utilizar la palabra clave val en el constructor para que sea accesible al público:

class Foo(val bar:String) { 

} 

cuanto a su pregunta: si esta es la única característica que necesita, no utilice las clases de casos, solo escriba con val.

Sin embargo, sería genial saber por qué las clases de casos no son buenas.

En el caso de las clases todos los argumentos de forma predeterminada son públicos, mientras que en la clase normal son todos privados.Pero puede ajustar este comportamiento:

scala> class Foo(val bar:String, baz: String) 
defined class Foo 

scala> new Foo("public","private") 
res0: Foo = [email protected] 

scala> res0.bar 
res1: String = public 

scala> res0.baz 
<console>:10: error: value baz is not a member of Foo 
       res0.baz 

Y aún así:

class Foo(private[mypackage] val bar:String) { 
    // will be visible only to things in `mypackage` 
} 

Para las clases de casos (gracias a @JamesIry):

case class Bar(`public`: String, private val `private`: String) 
+0

true' val' guarda 1 caracter. Sin embargo, sería genial saber por qué las clases de casos no son buenas. – Jus12

+0

@ Jus12 He hecho una edición de acuerdo con su pregunta, en resumen: es más flexible –

+2

En realidad, puede escribir la clase de caso Foo (val bar privado: String) para obtener campos privados en las clases de caso –

4

Puede utilizar la anotación BeanProperty para generar automáticamente captadores similar a Java

import scala.reflect.BeanProperty 
case class Foo(@BeanProperty bar:String) 

Ahora Foo tiene un método GetBar que devuelve el valor bar.

Tenga en cuenta que esto solo es útil si tiene un buen motivo para utilizar getters tipo java (por las razones típicas es que necesita que su clase sea un java adecuado para trabajar con bibliotecas java que esperan java beans y usa la reflexión para acceder a las propiedades del bean).

De lo contrario, simplemente acceda directamente al valor bar, esta es "la forma scala".

Ver http://www.scala-lang.org/api/current/index.html#scala.reflect.BeanProperty

+0

También en este caso preciso también se podría nombre el valor 'getBar'in en primer lugar, pero esto va en contra de las convenciones scala. –

+0

note - es 'import scala.beans.BeanProperty' en Scala 2.12 – Alex

Cuestiones relacionadas