En Scala veo una característica como variable privada de objeto. De mi experiencia en Java no muy rica, aprendí a cerrar todo (hacerlo privado) y abrir (proporcionar accesos) si es necesario. Scala introduce un modificador de acceso aún más estricto. ¿Debería usarlo siempre por defecto? ¿O debería usarlo solo en algunos casos específicos donde necesito restringir explícitamente el cambio de valor de campo incluso para objetos de la misma clase? En otras palabras, ¿cómo debo elegir entre
class Dummy {
private var name = "default name"
}
class Dummy {
private[this] var name = "default name"
}
El segundo es más estricto y me gusta, pero ¿debo usarlo siempre o solo si tengo una razón de peso?
EDITADO: Como veo aquí private[this]
es solo un subcase y en lugar de this
puedo usar otros modificadores: "paquete, clase u objeto singleton". Así que lo dejo para algún caso especial.
Respuestas:
No creo que importe demasiado, ya que cualquier cambio solo afectará a una clase de cualquier manera. Así que la razón más importante para preferir
private
sobreprotected
máspublic
no se aplica.Úselo
private[this]
donde el rendimiento realmente importa (ya que obtendrá acceso directo al campo en lugar de métodos de esta manera). De lo contrario, simplemente se asientan en un estilo para que la gente no tiene que averiguar por qué esta propiedad esprivate
y que uno esprivate[this]
.fuente
private
todos modos, por lo que el impacto debe ser cero o al menos muy muy pequeño.Hay un caso en el que
private[this]
se requiere compilar el código. Esto tiene que ver con una interacción de notación de varianza y variables mutables. Considere la siguiente clase (inútil):Entonces, esta clase está diseñada para contener un valor opcional, devolverlo como una opción y permitir que el usuario llame
makeEmpty
para borrar el valor (de ahí la var). Como se dijo, esto es inútil excepto para demostrar el punto.Si intenta compilar este código con en
private
lugar deprivate[this]
, fallará con el siguiente mensaje de error:Este error se produce porque el valor es una variable mutable en el tipo covariante T (+ T) que normalmente es un problema a menos que se marque como privado para la instancia con
private[this]
. El compilador tiene un manejo especial en su verificación de varianza para manejar este caso especial.Entonces es esotérico, pero hay un caso en el que
private[this]
se requiere un cambioprivate
.fuente
private var name
es accesible desde cualquier método declass Dummy
(y su compañeroobject Dummy
).private[this] var name
es accesible desde métodos dethis
objeto solamente, no desde otros objetos declass Dummy
.fuente
para que pueda hacer esto en privado cada vez que lo desee, pero puede tener algún problema si necesita referirlo
fuente
private[this]
no es igual aprotected[this]
.protected[this]
permite que las instancias de subclase accedan al miembro.this.y == that.y
usando ni privado ni privado [esto], acabo de probar ambosEsto se probó con scala 2.11.5. Considere el código a continuación
se compilará y funcionará como este código java (1.8)
sin embargo, si usa el modificador '[this]', el código siguiente no se compilará
Esto se debe a que en el primer caso, 'x' es accesible a nivel de clase, mientras que en el segundo caso es más estricto a nivel de instancia. Significa que solo se puede acceder a 'x' desde la instancia a la que pertenece. Entonces 'this.x' está bien pero 'other.x' no lo está.
Puede consultar la sección 13.5 del libro "Programación en Scala: una guía completa paso a paso" para obtener más detalles sobre los modificadores de acceso.
fuente
private[this]
significa. Tenga en cuenta la primera oración.Al agregar el alcance al modificador privado ( privado [X] ), se comporta efectivamente como una X "hasta", donde X designa algún paquete, clase u objeto singleton que lo incluye.
Por ejemplo, private [bar] , donde bar es un paquete, significa que cada instancia de cada clase que pertenece al paquete bar puede acceder a cualquier miembro que el modificador esté restringiendo.
En el caso de privado [esto] , significa que el miembro solo es accesible para cada instancia. Esto se vuelve más claro en el siguiente ejemplo:
Como puede ver, el segundo Foo no tiene ningún problema ya que cualquier instancia puede acceder al val privado i. Sin embargo, para el primer Foo hay un error ya que cada instancia no puede ver la i de otra instancia.
Es una buena práctica escribir en privado [esto] ya que impone una restricción mayor.
fuente
En la mayoría de los lenguajes de programación OOP como Java, los campos / métodos privados significan que estos campos / métodos privados no son accesibles fuera de la clase. Sin embargo, las instancias / objetos de la misma clase pueden tener acceso a los campos privados de los objetos mediante el operador de asignación o mediante el constructor de copias. En Scala, privado [this] es un objeto privado, lo que asegura que cualquier otro objeto de la misma clase no pueda acceder a los miembros privados [this].
Ejemplo
1.Sin privado [esto]
2.Usando privado [esto]
Por lo tanto, privado [esto] asegura que el campo _password solo sea accesible con esto.
fuente
Para profundizar en el tema del rendimiento que ha mencionado Alexey Romanov, aquí están algunas de mis conjeturas. Citas del libro "Programación en Scala: una guía completa paso a paso, segunda edición" Sección 18.2:
Para probarlo, este código provocará un error de compilación:
Scala se queja
error: ambiguous reference to overloaded definition
. Agregar la palabra clave override adata_=
no ayudará debería probar que el método es generado por el compilador. Agregar unaprivate
palabra clave a una variabledata
seguirá causando este error de compilación. Sin embargo, el siguiente código se compila bien:Entonces, supongo
private[this]
que evitará que scala genere métodos getter y setter. Por lo tanto, acceder a dicha variable ahorrará la sobrecarga de llamar al método getter y setter.fuente
Es mejor usarlo
private[this]
si planea sincronizar la variable.Aquí un buen ejemplo de la guía de estilo scala del equipo Spark :
fuente