2017-08-03 61 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不是问题。 –

相关问题