Soru Anlamak için Scala “<-”


Scala'nın her zaman her şeye "doğal bir açıklaması" olduğunu buldum. Her zaman "ohh, ama bu sadece bu ve bu ve bu parametre ile bu nesne çağrılan bir işlev" gibi bir şey. Bir anlamda, diğer dillerden bildiğimiz kadarıyla hiçbir şey gerçekten derleyici-sihir değildir.

Sorum şu <- Aşağıdaki kodda kullanılan operatör:

for(i <- 0 to 10) println(i)

Bu örnekte bunun gibi bir şeye yeniden yazıldığını görebiliyorum:

0.to(10).foreach((i:Int)=>println(i))

ama bu nasıl olduğunu açıklamıyor ben foreach fonksiyonu içinde anonim fonksiyona taşındı. Yazdığınız noktada ben Bu bir nesne değildir ve henüz bir bildirilen değişken değildir. Öyleyse nedir ve nasıl foreach içerisine taşınır?

Benim tahminimce sonunda bir şey keşfettim derleyici sihir

Zaman ayırdığın için teşekkürler.

Netleşmeştirmek, Benim sorum: <- işleci kodun 1. satırında nasıl çalışır, çünkü bir işlev olarak çağrılabilir bir nesne değildir.


23
2017-09-20 17:59


Menşei




Cevaplar:


<- olduğu gibi dil tanımlı bir anahtar kelime sembolüdür => ama farklı kontrastta -> (tanımlı bir sembol). Temel Scala dilbilgisinin bir parçası olduğu için, bağlayıcılar oluşturmak için kullanılabilir ( i örneğinizde), kullanıcı tanımlı yapılar tarafından yapılamayacak bir şeydir.


18
2017-09-20 19:37



Bu cevap gibi görünüyor. Mümkünse bunu belgelemenizi öneririm, şu anda maviden farklıdır. - Felix
@Felix: Belirtimde belgelenmiştir. Ve piyasada mevcut olan her Scala kitabı da bunu kapsamaktadır. - missingfaktor
oh evet, henüz bir kitap almadım. kesin 2.8 kitabını bekliyor - Felix
Bu 2.8'de hiç yeni değil. Dili sadece 2.7 çağında aldım, ama eminim ki, dilin başlangıcına çok daha fazla geri dönüyor. - Randall Schulz
@Felix: artima.com/shop/programming_in_scala_2ed - Randall Schulz


Dave'in cevabını artırmak için, Scala dil belirtiminden 'anlama-anlama' için bir çeviri şeması:

Anlama for (enums) yield e İfadeyi değerlendirir e Sayımcı enumlar tarafından oluşturulan her bir bağlanma için. Bir sayım dizisi her zaman bir jeneratörle başlar; Bu, başka jeneratörler, değer tanımları veya korumaları tarafından takip edilebilir.

Bir jeneratör p <- e bir ifadeden bağlar üretir e bir şekilde desenle eşleşir p. Bir değer tanımı val p = e değer adını bağlar p (veya bir desende birkaç isim p) ifadenin değerlendirilmesinin sonucuna e. Bir bekçi if e numaralandırılmış bağlamaları kısıtlayan bir boole ifadesi içerir.

Jeneratörler ve muhafızların kesin anlamı, isimlere çeviri ile tanımlanır.   dört yöntemin map, filter, flatMap, ve foreach. Bu yöntemler farklı taşıyıcı tipleri için farklı şekillerde uygulanabilir.

Çeviri şeması şöyledir. İlk adımda her jeneratör p <- ep türü için reddedilemez (§8.1) e tarafından değiştirildi

 p <- e.filter { case p => true; case _ => false }

Daha sonra, tüm kurallar ortaya çıkana kadar aşağıdaki kurallar tekrar tekrar uygulanır.   ortadan kaldırdı.

  • Anlama for (p <- e) yield e0 çevrildi e.map { case p => e0 }.

  • Anlama for (p <- e) e0 çevrildi e.foreach { case p => e0 }.

  • Anlama for (p <- e; p0 <- e0 . . .) yield e00, nerede . . . jeneratörler veya korumaların bir (muhtemelen boş) dizisidir, çevrilir   için:
    e.flatMap { case p => for (p0 <- e0 . . .) yield e00 }.

  • Anlama for (p <- e; p0 <- e0 . . .) e00 nerede . . . (muhtemelen boş) bir jeneratör veya koruma dizisidir, aşağıdakilere çevrilir:   
    e.foreach { case p => for (p0 <- e0 . . .) e00 } .

  • Bir jeneratör p <- e bir bekçi takip etti if g tek bir jeneratöre çevrilir:
    p <- e.filter((x1, . . . , xn) => g )
     nerede x1,. . . , xnserbest değişkenler   arasında p.

  • Bir jeneratör p <- e sonra bir değer tanımı val p0 = e0 çevrildi   aşağıdaki değer çiftleri jeneratörüne, x ve x0 taze isimler:

    val (p, p0) <- 
      for(x@p <- e) yield { val x0@p0 = e0; (x, x0) }
    

59
2017-09-20 18:59



Tamam, okuduktan sonra her şeyi anlamıyorum, ama ilginç :-) Bu nereden aldın? - Felix
@Felix: Cevabın en üstünde söylediğim gibi, dil özelliklerinden (www.scala-lang.org adresinden indirilebilir) - missingfaktor


Bu durumda, gerçekten derleyici büyüsü biraz. Anlatıdan süzgeç / harita / flatmap formuna çeviri, özel güncelleme formlarının dönüştürülmesi ve uygulama yöntemleri gibi özel bir desugaring yöntemidir.


7
2017-09-20 18:23