我正在尝试使用前置于Long
的单个LongRange
值生成序列。这有效:
val seq = buildSequence<Long> {
yield(2)
yieldAll(3L..5)
}
但是试图概括它,我似乎无法构建一个我可以成功调用的扩展函数:
infix fun Long.join(R: LongRange): Sequence<Long> {
val start = this
return buildSequence<Long> {
yield(start)
yieldAll(R)
}
}
当我试图打电话时:
(2 join 3..5).forEach { /* do something */ }
我得到了
错误:(26,20)Kotlin:未解决的参考。由于接收器类型不匹配,以下候选者均不适用: public infix fun Long.join(R:LongRange):在main.kotlin中定义的序列
似乎编译器认识到函数的签名是 close 到我想要实现的目标,但我对“接收器类型不匹配”的含义显然很模糊。 / p>
答案 0 :(得分:6)
'接收器类型不匹配'错误意味着passed as a receiver to the extension function(即它被调用的内容)与声明的接收器类型不对应。
Kotlin与Java不同,doesn't promote numbers更广泛的数字类型,您必须在代码中使用Long
literals,其中Long
是预期的:
(2L join 3L..5).forEach { /* do something */ }
在这里,使用2
作为接收者不是一种选择,因为预期会有Long
。但是3L..5
使用5
是正常的,因为有Long.rangeTo
重载接受Int
并返回LongRange
。
当有自动提升时,唯一的例外是当您将Int
字面值分配给另一个整数类型的变量时,以及将Int
字面值作为期望另一个整数类型的函数的参数(如上所述,它不适用于接收器)。
val a: Long = 5 // OK
fun f(l: Long) { }
f(5) // OK
val b = 5
val c: Long = b // Error
f(b) // Error