Scala 目标类型的隐式转换和按名称参数
考虑以下代码:Scala 目标类型的隐式转换和按名称参数,scala,Scala,考虑以下代码: class DelayedInt(val值:Int){ var locked=true } 对象延迟{ 隐式def delayedintotoint(del:delayedintt)={ if(del.locked)抛出新的RuntimeException(“尚未!”) del.value } } 对象主体{ 变量队列:Seq[()=>Int]=Seq.empty def queueInt(int:=>int):单位={ 队列:+=int_ } def printQueue():
class DelayedInt(val值:Int){
var locked=true
}
对象延迟{
隐式def delayedintotoint(del:delayedintt)={
if(del.locked)抛出新的RuntimeException(“尚未!”)
del.value
}
}
对象主体{
变量队列:Seq[()=>Int]=Seq.empty
def queueInt(int:=>int):单位={
队列:+=int_
}
def printQueue():单位=
对于(f我的理解是,在这两种情况下,queueInt(5+di)
和queueInt(di)
,隐式转换应该在任何计算发生之前发生。queueInt
接受按名称参数,然后由于int
语法,它向queue:Seq[()=>int]添加了一个未应用的函数
,因此在queueInt
完成后不会对传入的参数求值。只有在调用printQueue()
时,queue
的元素函数才会因f.apply()
调用而求值
在println(5+di)
的情况下,参数不是按名称传递的,因此隐式转换后,它在传递到println
之前进行计算,因此抛出,但隐式转换仍然首先发生,就像queueInt
情况一样
这里似乎没有发生任何奇怪的事情。我的理解是,在这两种情况下,queueInt(5+di)
和queueInt(di)
,隐式转换应该在进行任何计算之前发生。queueInt
接受一个按名称参数,然后由于int
语法,它向queue:Seq[()=>int]
添加了一个未应用的函数,因此在queueInt
完成后不会对传入的参数进行计算。仅当printQueue()时如果队列的元素函数由于f.apply()调用而求值,则调用
在println(5+di)
的情况下,参数不是按名称传递的,因此隐式转换后,它在传递到println
之前进行计算,因此抛出,但隐式转换仍然首先发生,就像queueInt
情况一样
这里似乎没有发生什么奇怪的事情
我不清楚的是Scala如何决定何时运行隐式转换
它不会直接插入,它只是在预期类型所需的位置插入,因此在编译器阶段之后,您的代码将成为
val di = new DelayedInt(42)
// println(5 + DelayedInt.delayedIntToInt(di)) // throws exception
queueInt(5 + DelayedInt.delayedIntToInt(di)) // OK
queueInt(DelayedInt.delayedIntToInt(di)) // OK
di.locked = false
printQueue()
然后,queueInt
案例对于by-name参数表现正常
它必须以某种方式确定结果将是正确的类型,而不使用隐式转换
这当然是基于类型的,不需要运行任何东西
我不清楚的是Scala如何决定何时运行隐式转换
它不会直接插入,它只是在预期类型所需的位置插入,因此在编译器阶段之后,您的代码将成为
val di = new DelayedInt(42)
// println(5 + DelayedInt.delayedIntToInt(di)) // throws exception
queueInt(5 + DelayedInt.delayedIntToInt(di)) // OK
queueInt(DelayedInt.delayedIntToInt(di)) // OK
di.locked = false
printQueue()
然后,queueInt
案例对于by-name参数表现正常
它必须以某种方式确定结果将是正确的类型,而不使用隐式转换
这当然是基于类型的,不需要运行任何东西。queueInt(5+di)
似乎没有在我的机器上运行。你能仔细检查一下吗?你是对的,它工作正常更有意义。我将修改问题为什么不是值类?queueInt(5+di)
似乎没有在我的机器上出现。你能仔细检查一下吗?你是对的,它工作正常更合理。我会修改问题为什么不是值类?我想我知道了,但我还是有点不清楚,所以我把问题留了下来。让我困惑的是Scala知道di
是=>Int
类型的,尽管如此呃,表面上不是。但是我假设类型系统可以推断,在没有实际运行代码的情况下?di
不是=>Int
类型,它是DelayedInt
。=>
构造没有改变类型,它正在改变传入参数的求值策略。我想我明白了,但我还是有点不明白很清楚,所以我把这个问题留了下来。让我困惑的是Scala知道di
是=>Int
类型,虽然表面上不是。但我假设类型系统可以推断,在没有实际运行代码的情况下,di
不是=>Int
类型,而是延迟的
。=>不是更改类型,而是更改传入参数的计算策略。