"Özel değer" ve "özel son değer" neden farklı?


100

Scala Reference'da bölüm 4.1'i görene kadar bunu düşünürdüm private valve private final valaynıydım:

Sabit bir değer tanımı formdadır

final val x = e

e sabit bir ifadedir (§6.24). Son değiştirici mevcut olmalıdır ve hiçbir tür açıklaması verilmemelidir. X sabit değerine yapılan referansların kendileri sabit ifadeler olarak ele alınır; üretilen kodda, tanımın sağ tarafı e ile değiştirilir.

Ve bir test yazdım:

class PrivateVal {
  private val privateVal = 0
  def testPrivateVal = privateVal
  private final val privateFinalVal = 1
  def testPrivateFinalVal = privateFinalVal
}

javap -c çıktı:

Compiled from "PrivateVal.scala"
public class PrivateVal {
  public int testPrivateVal();
    Code:
       0: aload_0       
       1: invokespecial #19                 // Method privateVal:()I
       4: ireturn       

  public int testPrivateFinalVal();
    Code:
       0: iconst_1      
       1: ireturn       

  public PrivateVal();
    Code:
       0: aload_0       
       1: invokespecial #24                 // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: iconst_0      
       6: putfield      #14                 // Field privateVal:I
       9: return
}

Bayt kodu, Scala Reference'ın dediği gibi: private valdeğildir private final val.

Neden gelmez scalać sadece tedavi private valolarak private final val? Altta yatan herhangi bir sebep var mı?


28
Başka bir deyişle: a valzaten değişmez olduğundan, finalScala'da anahtar kelimeye neden ihtiyacımız var ? Derleyici neden hepsine valaynı şekilde final valdavranamıyor?
Jesper

privateKapsam değiştiricinin package privateJava'daki ile aynı semantiğe sahip olduğuna dikkat edin . Söylemek isteyebilirsin private[this].
Connor Doyle

5
@ConnorDoyle: Özel paket olarak mı? Sanmıyorum: privatesadece bu sınıfın örneklerine görünür olduğu anlamına gelir, private[this]yalnızca bu örnek - aynı sınıfın örnekleri dışında , privatekimsenin (aynı paketten dahil) değere erişmesine izin vermez.
Make42

Yanıtlar:


81

Yani, bu sadece bir tahmin, ancak Java'da, sağ tarafta bir değişmez olan son statik değişkenlerin sabitler olarak bayt koduna satır içi olarak girilmesi Java'da çok yıllık bir rahatsızlıktı. Bu kesinlikle bir performans avantajı sağlar, ancak "sabit" değiştiğinde tanımın ikili uyumluluğunun bozulmasına neden olur. Değerinin değişmesi gerekebilecek son bir statik değişkeni tanımlarken, Java programcıları, değeri bir yöntem veya kurucu ile başlatmak gibi hacklere başvurmak zorundadır.

Scala'daki bir değer Java anlamında zaten son haldedir. Görünüşe göre Scala'nın tasarımcıları "sabit değeri satır içi yapma izni" anlamına gelmek için final değiştirici kullanıyorlar. Bu yüzden Scala programcıları, bilgisayar korsanlarına başvurmadan bu davranış üzerinde tam kontrole sahiptirler: eğer hiç değişmemesi gereken ama hızlı olan bir satır içi sabit isterlerse, "son val" yazarlar. İkili uyumluluğu bozmadan değeri değiştirme esnekliği istiyorlarsa, sadece "val".


9
Evet, özel olmayan valslerin nedeni budur, ancak özel vals açıkça diğer sınıflarda sıralanamaz ve aynı şekilde uyumluluğu bozamaz.
Alexey Romanov

3
Ben değiştiğinde herhangi bir ikili uyumluluk sorunu var mı private valhiç private final val?
Yang Bo

1
@ steve-waldman Affedersiniz val, ikinci paragrafınızda mı demek istediniz ?
Yang Bo

1
Java'da ikili uyumluluğa ilişkin son statik değişkenler hakkındaki ayrıntılar - docs.oracle.com/javase/specs/jls/se7/html/…
Eran Medan

8

Sanırım buradaki karışıklık, değişmezliği finalin anlambilimiyle karıştırmaktan kaynaklanıyor. vals, alt sınıflarda geçersiz kılınabilir ve bu nedenle, açıkça belirtilmedikçe nihai olarak değerlendirilemez.

@Brian REPL, satır düzeyinde sınıf kapsamı sağlar. Görmek:

scala> $iw.getClass.getPackage
res0: Package = package $line3

scala> private val x = 5
<console>:5: error: value x cannot be accessed in object $iw
  lazy val $result = `x`

scala> private val x = 5; println(x);
5

1
Ben bahsediyorum private val. Geçersiz kılınabilir mi?
Yang Bo

Hayır, özel vals geçersiz kılınamaz. Bir alt sınıfta aynı ada sahip başka bir özel değeri yeniden tanımlayabilirsiniz, ancak bu tamamen farklı bir değerdir ve aynı ada sahiptir. (Eskisine yapılan tüm atıflar hala eskisine atıfta bulunur.)
aij

1
bir sınıf bağlamına hiç girmeden yorumlayıcıda son bir değer (veya hatta son bir değişken) yapabildiğim için, bu sadece ağır basan davranış gibi görünmüyor.
nairbv
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.