2013-09-04 4 views
19

Was ist der Unterschied zwischen einem privaten var-Konstruktorparameter und einem Konstruktorparameter ohne val/var? Sind sie in Bezug auf Umfang/Sichtbarkeit identisch?Scala-Konstruktorparameter

Ex:

class Person(private var firstName:String, lastName:String) 
+0

Überprüfen Sie diese Frage: http://stackoverflow.com/questions/15639078/scala-class-constructor-parameters – danielkza

+0

Dies hat eine bessere Erklärung: http://stackoverflow.com/questions/14694712/do-scala- constructor-parameters-default-to-private-val – lcn

Antwort

24

Ja, es gibt zwei wichtige Unterschiede. Zunächst einmal für den einfachen Fall: Konstruktorparameter ohne die Schlüsselwörter var oder val sind keine veränderbaren Variablen - ihre Werte können im Rumpf der Klasse nicht geändert werden.

Auch wenn wir uns auf das Schlüsselwort val beschränken, besteht dennoch ein Unterschied zwischen private val und Schlüsselwort-freien Parametern. Beachten Sie Folgendes:

class Person(private val firstName: String, lastName: String) 

Wenn wir mit javap -v Person in der kompilierten Klasse aussehen, wir werden sehen, dass es nur ein Feld hat, für firstName. lastName ist nur ein Konstruktor Parameter, das heißt, es Garbage Collection sein kann, nachdem die Klasse initialisiert wird, usw.

Der Compiler intelligent genug, um zu wissen, wann der Wert lastName wird nach der Initialisierung benötigt werden, und es wird ein erstellen Feld dafür in diesem Fall. Betrachten Sie die folgende Variante:

class Person(private val firstName: String, lastName: String) { 
    def fullName = firstName + " " + lastName 
} 

Der Compiler kann sagen, dass es später den Wert von lastName brauchen, und wenn wir javap wieder überprüfen wir werden sehen, dass die Klasse hat zwei Felder (beachten Sie, dass, wenn wir definiert hatten fullName als val anstelle von def, würde es nur ein Feld haben).

Schließlich beachten Sie, dass, wenn wir firstNameObjekt-private statt privaten Klassen machen, es funktioniert genau wie eine normale alte Keyword-less Konstruktorparameter:

class Person(private[this] val firstName: String, lastName: String) 

Dies funktioniert auch mit var statt val:

class Person(private[this] var firstName: String, lastName: String) 

Beide Klassen haben keine Felder. Weitere Details zum Objekt-privaten Zugriff finden Sie in Abschnitt 5.2 von the language specification.

+1

Willst du damit sagen, dass es in Situationen wie dem Beispiel mit 'def fullName 'keinen Unterschied zwischen einem **' privaten Wert' ** und einem Parameter ohne Schlüsselwort gibt? – RussAbbott

1

als Ergänzung, wenn Ihre Klasse eine Fallklasse ist, werden alle Konstruktorparameter automatisch öffentliche Felder sein.

Der Compiler wird sich über das private Schlüsselwort beschweren, wenn es existiert, und für die Parameter ohne val/var, egal, ob sie in irgendwelchen defs verwendet werden oder nicht, werden öffentliche Felder für sie generiert.