2017-08-03 113 views
6

在Scala中,如果我有變量聲明,例如將字符或變量分配給字符時的Scala行爲

var x: Char = 'a' 

如果我然後試着通過加1來更新這個字符,

x = x + 1 

我得到一個編譯錯誤:類型不匹配,找到Int需要的字符。不過,我可以做到這一點沒有編譯錯誤:

x = 'a' + 1 

我猜這事做與文字值VS對象,但是,我試圖讓我的頭周圍的確切行爲。您可以清楚地將字面整數賦值給Char,例如97,您也可以分配97-32的結果。但是,如果我說97-32 + 5然後我得到一個類型不匹配的錯誤。編譯器在什麼時候區分導致字面的表達式和導致對象的表達式?

回答

1

作業是這裏的關鍵。 請看下面REPL會話:

[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> 

因此,大家可以看到,除非你試圖重新分配變量值一切順利。當你寫'a'+1x + 1它被轉換爲Int。 因此,當您最後嘗試x = x + 1重新分配時,則您正在嘗試將Int值分配給Char變量。這解釋了爲什麼會出現編譯錯誤。

Char伴侶對象中有implicit def char2int(x: Char): Int方法。 我認爲在var x:Char = 'a' + 1發生的第一件事就是調用此方法將'a'轉換爲97.然後將97加1,均爲Int s。然後,變量x以與在val y:Char = 98中相同的方式得到實例化。我認爲這解釋了變量初始化如何工作。

+1

這不回答爲什麼'變種X:字符= A + 1'作品,但'X = X + 1 '不。在第一次賦值時,「a + 1」隱式轉換爲「Char」,但在重新分配時它不會。爲什麼? –

+0

我編輯了我的答案。如果這與我認爲的不同,請投票給我的答案刪除,因爲那意味着我不瞭解底層的東西。 –

+0

也讓我們區分「第一作業」和「初始化」,因爲我認爲這很重要。變量初始化與值初始化沒有區別。我的意思是'val x:Char ='a'+ 1'與這個問題的'var x:Char ='a'+ 1'相同。 –

1

對於輸入文字in the spec有一個特殊的規則。

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.

可以讓你寫:

scala> 97 : Char 
res0: Char = a 

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

鬼祟地,他們在這裏的意思是常量表達式。但是常量表達式的definition是特定於平臺的,因此技術上res1也可能無法編譯,如果它不是恆定摺疊的。

一個相關的問題有關constant folding in scaladoc顯示類型下scaladoc檢查怪異的損失:

$ ~/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

如果我根據spec對該段的解釋是正確的,那麼'a'+ 1必須產生一個整數字面量(98),然後它可以合法地分配給一個類型爲Char的變量,因爲它在由那種類型?鑑於x + 1不能產生文字,所以這條規則不適用。它是否正確? – Tranquility

+0

是的,當然'x + 1'不是一個常量表達式或文字,'x'是一個運行時值。我不清楚「x + y + z」是否必須是常量摺疊的文字(如果值是常量)。 Scaladoc行爲是一個錯誤還是一個實現工件?在scalac中,你可以不斷摺疊。由於沒有人再寫文檔,scaladoc不是問題。 –

相關問題