2017-08-03 103 views
6

Scala'da, bir değişken bildirimi varsa, ör. Bu satırı, 1'i ekleyerek, örn.Scala davranışı, değişkenlere veya değişkenlere Char atanırken,

x = x + 1 

Derleme hatası alıyorum: Tür uyuşmazlığı, bulundu Int gerekli Char. Ancak, bir derleme hatasız yapabilirsiniz:

x = 'a' + 1 

bu nesneler vs edebi değerleri ile ilgisi vardır tahmin ediyorum, ancak, kesin davranış kafamı almaya çalışıyorum. Tam olarak bir tamsayı tam olarak bir Char'e atayabilirsiniz, ör. 97 ve ayrıca 97-32 sonucunu da atayabilirsiniz. Ancak 97-32 + 5 dersem, o zaman bir tür uyuşmazlığı hatası alırım. Derleyici hangi noktada bir nesneyle sonuçlanan bir değişmez ile sonuçlanan bir ifade arasında ayrım yapar?

cevap

1

Atama, burada anahtardır. Aşağıdaki REPL oturumunda Görünüş:

[email protected] ~ $ scala 
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> val x:Char = 'a' 
x: Char = a 

scala> x + 1 
res0: Int = 98 

scala> var y:Char = 'a' 
y: Char = a 

scala> y + 1 
res1: Int = 98 

scala> y = y + 1 
<console>:8: error: type mismatch; 
found : Int 
required: Char 
     y = y + 1 
      ^

scala> 

Yani değişkeni yeniden atamak için Denemeden ne gördüğünüz gibi her şey iyi gider değer verir. 'a'+1 veya x + 1 yazdığınızda, Int'a dönüştürülür. Nihayet, x = x + 1 yeniden atandığınızda,değişkenine Int değerini atamaya çalışıyorsunuz. Bu, derleme hatasının neden oluştuğunu açıklar.

Char tamamlayıcı nesnesinde implicit def char2int(x: Char): Int yöntemi vardır. var x:Char = 'a' + 1 'da bence ilk olan şey,' a 'yi 97'ye dönüştürmek için bu yöntemin çağrılmasıdır. O zaman 97, her ikisi de Int s olarak eklenir. Daha sonra x değişkeni val y:Char = 98 ile aynı şekilde örneklenir. Bu, değişken başlatmanın nasıl çalıştığını açıklar.

+1

Bu cevap vermezse neden 'var x: Char = a + 1 'çalışır, ancak' x = x + 1 yapmaz. İlk atamada “a + 1” ifadesi dolaylı olarak “Char” a dönüştürülür, ancak yeniden atama yapılmaz. Niye ya? –

+0

Cevabımı düzenledim. Bu düşündüğümden farklı çalışırsa, lütfen cevabımı silme için oy verin, çünkü o zaman temeldeki şeyleri anlamadığım anlamına gelir. –

+0

Ayrıca "ilk atama" ve "başlatma" arasında ayrım yapalım çünkü bence bu önemli. Değişken başlatma, değer başlatmadan farklı değildir. Ben val x: Char = 'a' + 1 ', bu değişken için var x: Char =' a '+ 1' ile aynıdır. –

1

in the spec yazımlarını yazmak için özel bir kural var. sağlayan

However, if the expected type pt of a literal in an expression is either Byte, Short, or Char and the integer number fits in the numeric range defined by the type, then the number is converted to type pt and the literal's type is pt.

Yazdığınız:

scala> 97 : Char 
res0: Char = a 

scala> 97 + 1 : Char 
res1: Char = b 

sinsice, burada sabit ifadeleri kastediyorum. Ancak sabit ifadenin definition platforma özgüdür, bu yüzden teknik olarak res1 da sabit katlanma olmasaydı derlemeyi başaramadı.

İlgili bir soru hakkında constant folding in scaladoc scaladoc altında kontrol tip garip kaybını gösterir:

$ ~/scala-2.12.3/bin/scaladoc -d /tmp folded.scala 
folded.scala:9: error: type mismatch; 
found : Int 
required: Char 
    x = 'a' - 32 + 5 
       ^
model contains 4 documentable templates 
one error found 
+0

Bu paragrafın spekülasyondan yorumlanması doğruysa, o zaman 'a' + 1 tamsayı değişkeni (98) ile sonuçlanmalıdır. Bu, daha sonra Char tarafından tanımlanan bir sayısal aralığa göre meşru bir şekilde atanabilir. Bu tip? X + 1, bir değişmez ile sonuçlanmamalıdır, bu nedenle bu kural geçerli değildir. Bu doğru mu? – Tranquility

+0

Evet, 'x + 1' sabit bir ifade veya değişmez değil, 'x' bir çalışma zamanı değeridir. Bana göre, x + y + z'nin sabit katlanmış bir literal olması gerekiyor (değerler sabitse). Scaladoc davranışı bir böcek mi yoksa uygulama artefakt mıdır? Scalac'da, sürekli katlanırsın. Artık kimse artık doktor yazmıyor, scaladok sorun değil. –