Scala yapıcı parametreleri varsayılan olarak özel değer mi?


128

Deniyorum:

class Foo(bar: Int)

vs:

class Foo(private val bar: Int)

ve onlar her yerde söyleyerek bulamadı, ancak aynı davranmasına görünmektedir (bar: Int)için Genişlediğinde(private val bar: Int) bu yüzden sorum şu, bunlar aynı / benzer mi?

Bir yan not olarak -Xprint:typer, bu kod parçaları üzerinde kullanmaya çalışıyorum ve ikincisinde fazladan bir satır dışında aynı kodu üretiyorlar. Bu ekstra satırı nasıl okuyabilirim?

..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..


..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  <stable> <accessor> <paramaccessor> private def bar: Int = Foo.this.bar;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..

Yanıtlar:


177

bar: Int

Bu ancak bir yapıcı parametresidir. Bu değişken kurucu dışında hiçbir yerde kullanılmazsa, orada kalır. Alan oluşturulmaz. Aksi takdirde private val baralan oluşturulur ve barona parametrenin değeri atanır. Alıcı yaratılmadı.

private val bar: Int

Böyle bir parametre bildirimi, private val barözel alıcıya sahip alan yaratacaktır . Bu davranış, parametrenin yapıcının yanında (örneğin içinde toString()ya da değil) kullanılmış olup olmadığına bakılmaksızın yukarıdaki davranışla aynıdır .

val bar: Int

Yukarıdakinin aynısı ancak Scala benzeri alıcı halka açıktır

bar: Int vaka sınıflarında

Durum sınıfları dahil edildiğinde, varsayılan olarak her parametrenin valdeğiştiricisi vardır.


15
Durum sınıflarında tüm parametreler "genel" hale gelecektir val.
drexin

6
Tanrım, zaman zaman gözlük takıyorum ama bu çok fazla.
om-nom-nom

1
@ om-nom-nom: üzgünüm, anlamadım. Daha okunaklı hale getirmek için biçimlendirmeyi / yapıyı iyileştirmeli miyim?
Tomasz Nurkiewicz

1
@TomaszNurkiewicz: varolmayan hem de (değişebilir) Sınıf özellikleri içine yapıcı parametreleri işlemek için kullanılabilir ve anlamlıdır caseve casesınıfları.
Randall Schulz

8
'Sabırsızlar İçin Scala' kitabındabar: Intprivate[this] val bar: Int
MyTitle

98

İlk durumda, baryalnızca bir yapıcı parametresidir. Ana kurucu sınıfın kendisinin içeriği olduğu için, içinde erişilebilir, ancak yalnızca bu örnekten. Dolayısıyla şuna neredeyse eşdeğerdir:

class Foo(private[this] val bar:Int)

Öte yandan, ikinci durumda barbir olan normal bir bu örneğe erişilebilir, böylece özel alan ve diğer örneklerini Foo. Örneğin, bu iyi derler:

class Foo(private val bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // access bar of another foo
  }
}

Ve çalışır:

scala> val a = new Foo(1)
a: Foo = Foo@7a99d0af

scala> a.otherBar(new Foo(3))
3

Ancak bu değil:

class Foo(bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // error! cannot access bar of another foo
  }
}

9
bu, kabul edilenden daha iyi bir cevaptır; çıplak bar: Intve arasındaki farkı vurgular private val ....
hraban
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.