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
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.
Tanımı ve beyan arasındaki fark nedir?...
Scala'nın durumu, sınıf ve sınıf ...
Parantez ve parantez, Scala, resmi ara...
Scala içinde JavaConverters ve JavaCon...
ScalaTest ve Scala Görüşler birim test...