Pytanie Parametry konstruktora Scala


Jaka jest różnica między prywatnym konstruktorem var a parametrem konstruktora bez val / var? Czy są one takie same pod względem zakresu / widoczności?

Dawny:

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

21
2017-09-04 21:00


pochodzenie


Sprawdź to pytanie: stackoverflow.com/questions/15639078/... - danielkza
To ma lepsze wytłumaczenie: stackoverflow.com/questions/14694712/... - lcn


Odpowiedzi:


Tak, istnieją dwie ważne różnice. Pierwszy dla łatwego: parametry konstruktora bez var lub val słowa kluczowe nie są zmiennymi zmiennymi - ich wartości nie można zmienić w treści klasy.

Nawet jeśli ograniczymy się do val słowo kluczowe, ale nadal istnieje różnica między private val i parametry bez słów kluczowych. Rozważ następujące:

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

Jeśli spojrzymy na skompilowaną klasę z javap -v Person, zobaczymy, że ma tylko jedno pole, dla firstName. lastName jest po prostu parametrem konstruktora, co oznacza, że ​​może zostać zbufowany po inicjalizacji klasy itp.

Kompilator jest wystarczająco inteligentny, aby wiedzieć, kiedy wartość lastName będzie potrzebne po zainicjowaniu, i utworzy w tym przypadku pole dla niego. Rozważ następującą odmianę:

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

Kompilator może powiedzieć, że może potrzebować wartości lastName później i jeśli sprawdzimy javap ponownie zobaczymy, że klasa ma dwa pola (zauważ, że gdybyśmy zdefiniowali fullName jak val zamiast def, miałby tylko jedno pole).

Wreszcie, zauważ, że jeśli zrobimy firstName  obiekt-prywatny zamiast class-privatedziała dokładnie tak, jak zwykły stary parametr konstruktora bez słów kluczowych:

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

Działa to nawet z var zamiast val:

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

Obie te klasy nie będą miały pól. Zobacz rozdział 5.2 specyfikacja języka aby uzyskać więcej szczegółowych informacji na temat dostępu obiektowego do prywatnego.


26
2017-09-04 21:40



Mówisz tak w sytuacjach takich jak przykład z def fullName nie ma różnicy między private val i parametr bez słów kluczowych? - RussAbbott


jako uzupełnienie, jeśli twoja klasa jest klasą case, wszystkie parametry konstruktora będą automatycznie polami publicznymi.

Kompilator będzie skarżył się na prywatne słowo kluczowe, jeśli istnieje, a dla parametrów bez wartości val / var, bez względu na to, czy są one używane, czy nie w jakichkolwiek defkach, będą generowane dla nich pola publiczne.


1
2018-05-06 06:41