我不明白为什么以下两个into
函数会导致Overload resolution ambiguity:
public fun <Fiz> Boo.into(block: FizMorphBuilder.() -> Unit): FizMorphBuilder defined in com.ltrojanowski.morph
public fun <Foo> Boo.into(block: FooMorphBuilder.() -> Unit): FooMorphBuilder defined in com.ltrojanowski.morph
当我明确指定类型boo.into<Foo>{}.morph()
时,为什么Kotlin不知道给定的type参数是哪个?
class FooMorphBuilder(
var a: String?,
var b: Double?,
var c: Int?,
var d: Float?,
var e: List<String>?
) : MorphBuilder<Foo> {
override fun morph(): Foo = Foo(a = a!!, b = b!!, c = c!!, d = d!!, e = e!!)
}
fun <Foo> Boo.into(block: FooMorphBuilder.() -> Unit): FooMorphBuilder = FooMorphBuilder(this.a,
this.b, this.c, this.d, this.e).apply(block)
和
class FizMorphBuilder(
var a: String?,
var b: Double?,
var c: Int?,
var d: Float?,
var e: List<String>?
) : MorphBuilder<Fiz> {
override fun morph(): Fiz = Fiz(a = a!!, b = b!!, c = c!!, d = d!!, e = e!!)
}
fun <Fiz> Boo.into(block: FizMorphBuilder.() -> Unit): FizMorphBuilder = FizMorphBuilder(this.a,
this.b, this.c, this.d, this.e).apply(block)
我能以某种方式解决这个问题吗?
答案 0 :(得分:2)
从JVM角度来看,函数在类型擦除后具有相同的类型,这类似于(在Java中):
public void into(Boo boo, Fucntion1 block);
在JVM级别上,此类解析不考虑函数返回类型。
为每个方法使用带有不同参数的@JvmName("unique name")
批注,以要求Kotlin编译器为JVM级别的方法生成唯一的名称。
UPD :这些功能不需要通用参数,即<Fiz>
和<Foo>
。您不要在声明中使用它们,而且Kotlin编译器也无法推断类型
UPD2 : 编译器将无法猜测您调用的lambda的类型,因此您可能还需要明确指定其类型,例如
val builder : FizMorphBuilder.() -> Unit = { /*the builder lambda */ }
val z = Boo().into(builder)
我们使用带有显式类型的声明来说明此时需要的确切生成器lambda签名。