将文字或变量分配给Char时的Scala行为

时间:2017-08-03 14:22:51

标签: scala char int variable-assignment

在Scala中,如果我有变量声明,例如

var x: Char = 'a'

如果我然后尝试通过添加1来更新此字符,例如

x = x + 1

我收到编译错误:类型不匹配,找到Int必需的Char。但是,我可以在没有编译错误的情况下执行此操作:

x = 'a' + 1

我猜这与文字值和对象有关,但是,我试图了解确切的行为。您可以清楚地为字符分配一个字面整数,例如97,你也可以分配97-32的结果。但是,如果我说97-32 + 5然后我得到类型不匹配错误。编译器在什么时候区分导致文字的表达式与导致对象的表达式?

2 个答案:

答案 0 :(得分:1)

分配是关键。 查看以下REPL会话:

alex@POSITRON ~ $ 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 :(得分:1)

键入文字in the spec有一个特殊规则。

  

但是,如果表达式中文字的预期类型pt是   Byte,Short或Char,整数就适合数字   由类型定义的范围,然后将数字转换为类型pt和   文字的类型是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