Kotlin:内联lambda和重载解析歧义

Kotlin:内联lambda和重载解析歧义,lambda,kotlin,overload-resolution,Lambda,Kotlin,Overload Resolution,我有一个简单的工厂模式,其中实现是通过重载解析来确定的。问题是Kotlin编译器抱怨内联lambda的“重载解析歧义…” class Foo(){ companion object Factory { fun create(x: Int, f: (Int) -> Double) = 2.0 fun create(x: Int, f: (Int) -> Int) = 1 } } fun main(args:Array<String

我有一个简单的工厂模式,其中实现是通过重载解析来确定的。问题是Kotlin编译器抱怨内联lambda的“重载解析歧义…”

class Foo(){
    companion object Factory {
        fun create(x: Int, f: (Int) -> Double) = 2.0
        fun create(x: Int, f: (Int) -> Int) = 1
    }
}

fun main(args:Array<String>){
    val a =  Foo.create(1,::fromDouble) //OK
    val b =  Foo.create(1,::fromInt)  //OK
    val ambiguous =  Foo.create(1){i -> 1.0}  //Overload resolution ambiguity?
}


fun fromDouble(int:Int)  = 1.0
fun fromInt(int:Int)  = 1
class Foo(){
伴星工厂{
乐趣创造(x:Int,f:(Int)->Double)=2.0
乐趣创造(x:Int,f:(Int)->Int)=1
}
}
趣味主线(args:Array){
val a=Foo.create(1,::fromDouble)//确定
val b=Foo.create(1,::fromInt)//确定
val-dimension=Foo.create(1){i->1.0}//重载解析歧义?
}
双精度(int:int)=1.0
乐趣来自int(int:int)=1

Kotlin编译器如何解析重载解析,以及为什么内联lambda被认为是不明确的?

Kotlin编译器只解析每个表达式一次。 所以,当编译器开始解析lambda表达式时,它应该知道lambda参数的类型。 因为这个编译器应该在开始查看lambda内部之前选择一个方法
create

例如:

fun foo(f: (Int) -> Int) = 1
fun foo(f: (String) -> String) = ""
val bar = foo { 
   println(it) 
   5
}
这里我们不能选择函数
foo
中的一个,因为它们没有一个比另一个更具体,所以我们不能开始解析lambda表达式,因为我们不知道
it
的类型


在您的示例中,理论上可以在选择特定函数之前开始解析lambda,因为对于所有潜在函数,lambda参数的类型都是相同的。但这是一个非常规逻辑,可能很难实现。

这似乎是一个bug,因为如果我将lambda像
{I:Int->1.0}那样强制转换为(Int)->Double,则没有歧义,但它表示不需要强制转换。另外,如果我将lambda提取到
vall={I:Int->1.0}
并使用它,同样没有歧义。请在bug跟踪器中搜索这个问题,如果没有,请创建一个新的文件:另一个有趣的事情是,如果您像@hotkey那样使用lambda,IDE会告诉您这是不必要的。但是当你移除它的时候,它会抱怨模棱两可。谢谢你的输入!我想这可能是个bug。在这里提交报告似乎仍然是一个错误。这是一个令人沮丧的问题。lambda上的过载分辨率对于数值应用是非常有用的。假设我有一个处理float、double和int的矩阵类。使用“重载解析”实例化将是
val ms=Mat44{I,j->1.0}
,现在我不得不将
val ms=Mat44({I:int,j:int->1.0}写成(int,int)->double)
,对于这样一个琐碎的任务来说,这简直是简单而愚蠢的冗长。非常感谢@erokhins的精彩解释!作为解决方法,您可以创建具有不同名称的函数:
fun Mat44Int2Double(f:(Int,Int)->Double)=Mat44(f)
。但它并不优雅……同样的问题也适用于构造函数中的lambda。你也会得到一个超负荷的模糊性。