SORU
24 Kasım 2009, Salı


Scala artış var ve val tanımı arasındaki fark nedir?

Scala var val bir tanım arasındaki fark nedir ve neden bu dil de gerekiyor mu? Neden var ve tersi üzerinde val seçerdiniz?

CEVAP
24 Kasım 2009, Salı


Diğerleri dediğim gibi, nesne val tamamı için atanmış değiştirilmesi ve nesne var Bir atanmış. Ancak, nesne, iç durumunda değişiklik olabilir. Örneğin:

class A(n: Int) {
  var value = n
}

class B(n: Int) {
  val value = new A(n)
}

object Test {
  def main(args: Array[String]) {
    val x = new B(5)
    x = new B(6) // Doesn't work, because I can't replace the object created on the line above with this new one.
    x.value = new A(6) // Doesn't work, because I can't replace the object assigned to B.value for a new one.
    x.value.value = 6 // Works, because A.value can receive a new object.
  }
}

Nesne değiştiremeyiz bu yüzden olsa bile, x, atadığı nesnenin durumunu değiştirebiliriz. Bunun temelinde, ancak, var vardı.

Şimdi, değişmezliğini tanıdı birçok nedenden dolayı iyi bir şeydir. Eğer bir nesnenin iç durumu değiştirmez ama önce, eğer kodu başka bir parçası değişiyor endişelenmenize gerek yok. Örneğin:

x = new B(0)
f(x)
if (x.value.value == 0)
  println("f didn't do anything to x")
else
  println("f did something to x")

Bu çok iş parçacıklı sistemleri ile özellikle önemli hale gelir. Çok iş parçacıklı bir sistemde, aşağıdaki olabilir:

x = new B(1)
f(x)
if (x.value.value == 1) {
  print(x.value.value) // Can be different than 1!
}

Eğer val özel olarak kullanıyorsanız ve temel veri yapılarını (diziler önlemek, scala.collection.mutable vs. Her şeyi.) sadece kullanmak, bu olmayacak emin olabilirsiniz. Bunu, bazı kod var tabii, hatta belki bir çerçeve, yansıma yapıyor hileler -- yansıması "değişmez" değerleri, ne yazık ki. değiştirebilirsiniz.

Birinci sebep bu, ama bunun için başka bir neden yoktur. var, kullandığınızda çok amaçlı var aynı yeniden içine cazip olabilir. Bu bazı sorunları var:

  • İnsanlar kod okuma kod bir parçası olarak bir değişkenin değerini bilmek için daha zor olacak.
  • Yeniden başlatma bazı kod yolu değişken, unutmayın ve yanlış değerleri kod içinde aşağı geçen sona erebilir.

Basitçe söylemek gerekirse, val kullanarak daha güvenli ve daha okunabilir kod yol açar.

O zaman, diğer tarafa gidebiliriz. Eğer val daha iyi ise, neden var? Bazı diller bu yolu sürdü, ama mutability performansı çok artırır durumlar vardır.

Örneğin, bir değişmez Queue. enqueue dequeue öyle şeyler ya, Queue yeni bir nesne olsun. Nasıl sonra, tüm öğeleri işleme hakkında gitmek istiyorsunuz?

Bir örnek ile devam edeceğim. Hadi basamaklı bir sıra var ki, onları bir dizi oluşturmak istiyorum. Eğer bu sırayla 2, 1, 3, bir kuyruk var, örneğin, numara 213 geri almak istiyorum. Hadi mutable.Queue: a ile çözmek

def toNum(q: scala.collection.mutable.Queue[Int]) = {
  var num = 0
  while (!q.isEmpty) {
    num *= 10
    num  = q.dequeue
  }
  num
}

Bu kod ve anlamak kolaydır. Ana dezavantajı geçirilen sıra bir kopyasını önceden yapmak zorunda toNum tarafından değiştirilmiş olmasıdır. Bu değişmezliğini tanıdı seni özgür kılan nesne yönetimi.

Şimdi, izin immutable.Queue: bu gizli

def toNum(q: scala.collection.immutable.Queue[Int]) = {
  def recurse(qr: scala.collection.immutable.Queue[Int], num: Int): Int = {
    if (qr.isEmpty)
      num
    else {
      val (digit, newQ) = qr.dequeue
      recurse(newQ, num * 10   digit)
    }
  }
  recurse(q, 0)
}

Önceki örnekte* *33, benim gibi izlemek için bazı değişken yeniden yapamam çünkü, özyineleme başvurmak istiyorum. Bu durumda, oldukça iyi bir performansa sahip olan kuyruk özyineleme. Ama bu her zaman böyle değil: bazen () okunabilir, basit iyi kuyruk özyineleme çözüm yok.

Bu kod aynı zamanda immutable.Queue var bir kullanım için yeniden yazabilirim unutmayın, ancak! Örneğin:

def toNum(q: scala.collection.immutable.Queue[Int]) = {
  var qr = q
  var num = 0
  while (!qr.isEmpty) {
    val (digit, newQ) = qr.dequeue
    num *= 10
    num  = digit
    qr = newQ
  }
  num
}

Bu kod hala verimli, özyineleme gerektiren değildir toNum çağırmadan önce sıra bir kopyasını olup olmadığını endişelenmenize gerek yok. Doğal olarak, kaçındım yeniden değişkenleri için başka amaçlar ve kod dışında bu işlevi görüyor, o yüzden gerek yok endişe değerleri değişen bir satıra gelecek ama ne zaman ben açıkça öyle.

Scala programcı eğer programcı en iyi çözüm olarak görüldüğü takdirde bunu yapmak için seçti. Diğer diller gibi kod zorlaştırmak için seçti. Scala (ve yaygın mutability ile herhangi bir dil) ödediği bedel derleyici olabilir aksi gibi kod optimize olarak çok zaman kaybı yok. Bunun için Java cevabı çalıştırma profiline göre kodu en iyi duruma getirme. Ve her tarafa artıları ve eksileri hakkında gidebiliriz.

Şahsen, Scala sağ dengesi, şimdilik grev düşünüyorum. Mükemmel, çok değil. Clojure Haskell hem çok ilginç fikirler Scala tarafından kabul edilmemiş olduğunu düşünüyorum, ama Scala de kendi avantajları vardır. Gelecekte ne kadar gelir göreceğiz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • hidetake takayama

    hidetake tak

    3 Mart 2009
  • Kassem G

    Kassem G

    25 EKİM 2006
  • MagmaRhino

    MagmaRhino

    16 Temmuz 2011