2010-02-11 21 views
16

,Scala'nın noktalı virgül çıkarımı burada neden başarısız? Scala 2.7.3 ile aşağıdaki kodu derleme üzerinde

package spoj 

object Prime1 { 
    def main(args: Array[String]) { 
    def isPrime(n: Int) = (n != 1) && (2 to n/2 forall (n % _ != 0)) 
    val read = new java.util.Scanner(System.in) 
    var nTests = read nextInt // [*] 
    while(nTests > 0) { 
     val (start, end) = (read nextInt, read nextInt) 
     start to end filter(isPrime(_)) foreach println 
     println 
     nTests -= 1 
    } 
    } 
} 

aşağıdaki derleme zamanı hatası alıyorum: Ben eklediğinizde

PRIME1.scala:8: error: illegal start of simple expression 
    while(nTests > 0) { 
    ^
PRIME1.scala:14: error: block must end in result expression, not in definition 
    } 
^
two errors found 

satırın sonunda bir noktalı virgül [*] olarak yorumladı, Program iyi derler. Scala'nın noktalı virgül çıkarımının neden belirli bir çizgide çalışmayı başaramadığını açıklayan herhangi biri olabilir mi?

+1

Sadece konu dışı, '2 ila n/2' yerine' 2 Math.sqrt (n) 'ile değiştirilebilir - her ne kadar daha iyi bir performans sağlayacağını bilmeme rağmen, kanonik çözümdür (Sanırım olmaz). – incarnate

+0

Bunun bir OLD iş parçacığı olduğunu biliyorum, ancak "next next" satırından sonra noktalı virgül yerleştirebilir misiniz? ya da bu bir problem çünkü 'nextInt' için bir argüman bulunmuyor mu? – Ramy

+0

@Ramy: Yanıtları okuyun. – missingfaktor

cevap

19

Bunun nedeni, scala, a foo b (a.foo(b) eşdeğeri) sözdizimini readInt aramanız için kullandığınız varsayılmaktadır. x sizin süre bloğu olan

var ntests = read nextInt x 

: Yani while döngü readInt (her ifade bir türü olan hatırlama) için argüman olduğunu varsayar ve dolayısıyla son açıklamasında beyanıdır vardır.

özellikle (aktörleri a ! b gibi) göz önünde o kullanımıyla tasarlanmıştır bir DSL ile çalışan sürece tercih noktası olarak, şimdi a foo b üzerinde her zamanki a.foo(b) sözdizimi kullanılarak iade ettik söylemeliyim

. Genel olarak işleri daha net hale getirir ve böyle garip şeyler tarafından ısırılmazsınız!

+4

+1 son paragraf – ziggystar

+0

içinde önerisi için bu bir OLD iş parçacığı olduğunu biliyorum, ancak okumak sonraki satırdan sonra noktalı virgül koymak olabilir? ya da bu bir problemdir, çünkü bir sonraki argümana verilen bir argüman yoktur? – Ramy

11

oxbow_lakes tarafından cevap Ek yorum ...

var ntests = read nextInt() 

noktalı virgül çıkarsama hakkında biraz daha eklemek için noktalı virgül

8

alternatif olarak sizin için şeyleri düzeltmek durumunda, Scala aslında bunu yapar iki aşamada. İlk olarak, dil özelliğine göre nl isimli özel bir jeton çıkarır. Ayrıştırıcı,'un bir deyim ayırıcısı olarak ve ayrıca noktalı virgül olarak kullanılmasına izin verir. Ancak, gramer tarafından diğer birkaç yerde de nl'a izin verilir. Özellikle, bir sonraki satırdaki ilk simge bir ifade başlatabildiğinde infix operatörlerinden sonra bir nl'a izin verilir - ve while bir ifadeyi başlatabilir, bu yüzden bu şekilde yorumlanır. Ne yazık ki, while bir ifadeyi başlatabilse de, while ifadesi bir infix ifadesinde kullanılamaz, dolayısıyla hata. Kişisel olarak, ayrıştırıcının çalışması için oldukça ilginç bir yol gibi görünüyor, ama bildiğim her şey için oldukça mantıklı bir mantık var.

olarak henüz başkalarına başka seçenek yalnızca tek bir nl birden çok nl s farklı bir yorumlama zorlar, infix operatörleri sonra izin verilir, çünkü [*] hattı ve ayrıca sorunu çözecektir while satır arasında boş yeni satır koyarak önerdi ayrıştırıcı tarafından.

İlgili konular