Ral*_*lph 5 scala primitive-types
在以下代码中:
def test(list: List[Any]): Unit = {
list.foreach {
v =>
v match {
case r: AnyRef => println(r + ": " + r.getClass.getName)
case d: Double => println(d + ": Double")
case f: Float=> println(f + ": Float")
case b: Byte => println(b + ": Byte")
case c: Char => println(c + ": Char")
case s: Short => println(s + ": Short")
case i: Int => println(i + ": Int")
case l: Long=> println(l + ": Long")
case b: Boolean => println(b + ": Boolean")
case _ => throw new IllegalArgumentException("Unknown type: " + v)
}
}
}
test(List(0L, 1.asInstanceOf[Int], 2.asInstanceOf[Short]))
Run Code Online (Sandbox Code Playgroud)
这是输出(Scala 2.8.1):
0: java.lang.Long
1: java.lang.Long
2: java.lang.Long
Run Code Online (Sandbox Code Playgroud)
为什么数字被提升为java.lang.Long?我怎么能这样做,以便他们保持他们的AnyVal类型或"盒装"到等效AnyRef类型?
Ste*_*eve 13
我认为答案在语言参考的第3.5.3节中:
因此,Scala推断Short,Int和Long之间的公共类型是Long,然后将非Long对象转换为Longs:
scala> List(0L, 0, 0: Short)
res1: List[Long] = List(0, 0, 0)
Run Code Online (Sandbox Code Playgroud)
如果您想使用整个弱一致性链,请尝试:
scala> List(0: Byte, 1: Short, 'c', 3, 4L, 5.0f, 6.0)
res2: List[Double] = List(0.0, 1.0, 99.0, 3.0, 4.0, 5.0, 6.0)
Run Code Online (Sandbox Code Playgroud)
而且,当然要说你想要一个List[Any],只需加入[Any]你的电话List:
scala> List[Any](0: Byte, 1: Short, 'c', 3, 4L, 5.0f, 6.0)
res11: List[Any] = List(0, 1, c, 3, 4, 5.0, 6.0)
Run Code Online (Sandbox Code Playgroud)
类型推断的工作原理是从最严格的类型(例如Nothing)开始,然后扩展直到一种类型可以包含所有内容。对于数值,这意味着从Int到扩大Long。但是现在,由于调用是有效的,List[Long](ls: Long*)所有数值都被提前提升。
因此,例如,所有这些都给出了相同的列表:
List(1, 2: Byte, 3: Long)
List(1L, 2, 3: Short)
List(1: Byte, 2: Long, 3: Byte)
Run Code Online (Sandbox Code Playgroud)
即一个List[Long](1L, 2L, 3L)。现在,如果您不喜欢这种行为,请将列表的类型指定为AnyValor Any:
List[Any](1, 2: Byte, 3: Long)
List.head.asInstanceOf[AnyRef].getClass // java.lang.Integer
Run Code Online (Sandbox Code Playgroud)
编辑: PS 如果您指定某个类型的常量,您应该只说明类型(例如(2: Short))而不是将其转换为该类型(例如2.asInstanceOf[Short])。
| 归档时间: |
|
| 查看次数: |
1790 次 |
| 最近记录: |