gpt4 book ai didi

scala - 意外的 Scala 默认值行为

转载 作者:行者123 更新时间:2023-12-01 13:07:42 25 4
gpt4 key购买 nike

为什么这里的默认值在显式分配给 val 时与直接打印时表现不同?

package blevins.example

class SimpleWrap[T] {
var t: T = _
def get = t
}

object App extends Application {
val swb = new SimpleWrap[Boolean]
val b = swb.get
println("b: " + b) // b: false
println("swb.get: " + swb.get) // swb.get: null

val swi = new SimpleWrap[Int]
val i = swi.get
println("i: " + i) // i: 0
println("swi.get: " + swi.get) // swi.get: null
}

我使用的是 2.8r19890。


编辑 - 当调用“get”并期待 Any 时,似乎会出现奇怪的情况。

  val any1: Any = swb.get
val any2: Any = b
println("any1: " + any1) // any1: null
println("any2: " + any2) // any2: false

最佳答案

我很确定这与基元的装箱/拆箱有关。如果您编写通用代码来处理基元,则必须对基元进行装箱,然后在将其用作基元的位置取消装箱。我不确定使用的是什么拆箱算法,但我想它是按照以下几行:

if(box == null) 
default value
else
box.unbox

因此,非常奇怪的是,我可能会补充说,简单包装类中字段 t 的默认值始终为 null ,因为该字段始终是盒装原语,因为泛型是通过类型删除在 JVM 级别实现的。因此,JVM 只看到 tObject 类型,值为 null。因此,方法 get 将始终返回 null,但是当泛型方法 get 应该返回原始类型时,null 被拆箱为默认值。

此外,通过反射进行一些探索确实表明该字段确实为 null

val sw = new SimpleWrap[Boolean]
sw.getClass.getDeclaredFields.map {
f => f.setAccessible(true)
f.get(sw)
}

哦,null 的乐趣。此问题的一个解决方案是使用 2.8 @specialised 注释,如果它已在您使用的夜间构建中实现的话。

或者,更好的是,Scala 编译器可以将这些字段默认为所用原语实际默认值的装箱默认值。例如,在 SimpleWrap[Boolean] 的情况下,t 将具有类型 Object 和值 java.lang。 Boolean(false) 在运行时。

编辑错误报告submitted .

另一个奇怪的事情:

val x: Int = null.asInstanceOf[Int] // 0
val y: Boolean = null.asInstanceOf[Boolean] // false

为了使泛型真正具有通用性并具有一致的行为,这是应该解决的问题!目前,您的 get 方法没有一致的行为。

-- 弗拉维乌西普西根

关于scala - 意外的 Scala 默认值行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1853397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com