Scala neden geri döndü, kırılmadı ve devam etmedi?


22

Scala'da yok breakveya continuebu yüzden bazı döngü davranışları biraz daha düşünmeyi gerektirir.

Döngünün erken sona ermesi, kuyruk özyinelemesini, istisnaları veya scala.util.control.Breaks(istisnaları kullanan) gerektirir.

Bunun mantığı goto, onlar gibi , akışı engelleyen akış yapıları olmaları ve daha iyi, daha az şaşırtıcı yollarla gerçekleştirilebilmeleridir.

Ancak aynı argümanlar için kullanılabilecek gibi görünüyor return.

Neden Scala kasten ihmal etmedi breakve continueancak return?


1
Ben dili yazarları olarak kuyruk özyinelemeye düşünün tahmin edebilirsiniz yinelemeyi inşa etmek yolunda. Bunu hayal edebiliyorum ve bazı ek temizleme makinelerine ihtiyacım var. OTOH , bir işlevi düzenli olarak sonlandırmanın bir yoludur ve tüm temizleme makineleri zaten zaten oradadır. breakcontinuereturn
9000,

1
breakable { for { break; } }Bir düşüncesi var ama sonradan ve muhtemelen verimli olmaktan uzak.
Joop Eggen,

Çünkü fonksiyonlarda bunun bir nedeni yoktur. Python'da da aynı. Ne zaman mola ile bir for-loop kullanıyorsanız, bunun yerine bir fonksiyon yazabilir, loop'unuzu fonksiyona dahil edebilir ve return kullanabilirsiniz. Bunun temiz kodla ilgili iyi bir fikir olmadığı bir durum düşünemiyorum. Performans için, temizleme daha iyi olabilir, ancak performans skalada en yüksek önceliğe sahip değildir.
valenterry,

2
Bu soru burada bir cevabı var gibi görünüyor: stackoverflow.com/questions/3770989/…
Michael Shaw

3
@PaulDraper: Sorunuzun cevabında breakve continuesorunuzda ve sorunuzun bağlantısında bulunur. Bu soru return, tam olarak bağlantı kurduğum sorunun neyle ilgili olduğunu ve en azından en çok oy alan kabul edilen cevabında cevaplandırıldığı soru. Bir araya getirilen iki cevap sorunuzu cevaplamazsa, belki soruyu netleştirmek için düzenleyebilirsiniz.
Michael Shaw,

Yanıtlar:


16

Ara ve Devam Et:

In Scala hakkında bir konuşma Martin Odersky mola içeren veya slayt 22 devam etmek değil 3 sebep verdi:

  • Onlar biraz zorunludur; birçok küçük işlevi daha iyi kullanın.
  • Kapaklarla nasıl etkileşime girileceği ile ilgili konular.
  • Onlar gerekli değil!

Ve sonra “Onları tamamen kütüphanelerde destekleyebiliriz” diyor. 23. slaytta, uygulayan kodu verir break. Scala'yı emin olmak için yeterince iyi bilmeme rağmen, slayttaki kısa pasajın uygulanması gereken tek şey gibi görünüyor breakve continuebu da benzer şekilde kısa olan kodda uygulanabilir.

Kütüphanelerdeki böyle şeyleri uygulayabilmek ana dili basitleştirir.

Martin Odersky, Lex Spoon ve Bill Venners tarafından 'Scala'da Programlama, İkinci Baskı' bölümünde, aşağıdaki açıklama verilmiştir:

Sen hiç söz edildiğine dikkatinizi çekmiş olabilir breakveya continue. Scala bu komutları dışarıda bırakır çünkü işlev değişmezleriyle iyi bir şekilde örüşmezler ... Döngü continueiçinde ne anlama geldiği açıktır while, ancak işlev değişkeni içinde ne anlama geleceği açıktır ? ... Programsız ve program yapmanın birçok yolu vardır breakve continueişlev değişmezlerinden faydalanırsanız, bu alternatifler genellikle orijinal koddan daha kısa olabilir.

Dönüş:

Dönüş bir fiil, bir şeyler yapmak için verilen bir komut olduğundan dönüşler stil açısından bir zorunluluk olarak kabul edilebilir. Fakat aynı zamanda tamamen işlevsel / bildirimsel bir şekilde de görülebilirler: işlevin dönüş değerinin ne olduğunu tanımlarlar (birden fazla geri dönüşü olan bir işlevde, sadece her biri kısmi bir tanım vermiş olsalar bile).

Aynı kitapta şöyle diyorlar return:

Açık bir returnifadenin yokluğunda , bir Scala yöntemi, yöntem tarafından hesaplanan son değeri döndürür. Yöntemler için önerilen stil aslında açık ve özellikle de çok sayıda returnifadeye sahip olmaktan kaçınmaktır . Bunun yerine, her yöntemi, döndürülen bir değer veren bir ifade olarak düşünün.

Yöntem sonlandırılır ve bir returnifade kullanılmasa bile bir değer döndürür , bu nedenle kapanışlarla ilgili bir işlem olamaz çünkü kapanmalar çalışma süresi olmaz.

İşlev değişmezleri ile iyi uyum sağlamakta da bir sorun olamaz, çünkü işlev yine de bir değer döndürmek zorundadır.


2
Geri dönüş ile ilgili olarak, bazı hafif tehlikeler var gibi görünüyor: tpolecat.github.io/2014/05/09/return.html
bbarker 24:16

0

Önceki cevapların , nispeten kısıtlayıcı olmayan bağlamlarda, Scala için breakya da continuedil genelinde anlambilim tanımlama problemlerine adalet getirdiğini düşünüyorum .

Bir yazdım küçük bir kütüphane bu tanımlar breakve continuedaha kısıtlı kapsamda: yineleme diziler üzerinde Scala ile hazır comprehensions. Bu konuya odaklanarak, anlambilimin açık ve mantıklı olması gerektiğine inanıyorum.

Kütüphaneye buradan ulaşabilirsiniz: https://github.com/erikerlandson/breakable

İşte kodda neye benzediğine dair basit bir örnek:

scala> import com.manyangled.breakable._
import com.manyangled.breakable._

scala> val bkb2 = for {
     |   (x, xLab) <- Stream.from(0).breakable   // create breakable sequence with a method
     |   (y, yLab) <- breakable(Stream.from(0))  // create with a function
     |   if (x % 2 == 1) continue(xLab)          // continue to next in outer "x" loop
     |   if (y % 2 == 0) continue(yLab)          // continue to next in inner "y" loop
     |   if (x > 10) break(xLab)                 // break the outer "x" loop
     |   if (y > x) break(yLab)                  // break the inner "y" loop
     | } yield (x, y)
bkb2: com.manyangled.breakable.Breakable[(Int, Int)] = com.manyangled.breakable.Breakable@34dc53d2

scala> bkb2.toVector
res0: Vector[(Int, Int)] = Vector((2,1), (4,1), (4,3), (6,1), (6,3), (6,5), (8,1), (8,3), (8,5), (8,7), (10,1), (10,3), (10,5), (10,7), (10,9))
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.