解决过载解决歧义

  • 本文关键字:解决 歧义 kotlin
  • 更新时间 :
  • 英文 :


我不明白为什么以下两个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

为什么 kotlin 在给定类型参数的情况下不知道当我显式指定类型boo.into<Foo>{}.morph()时选择哪一个?

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)

我可以以某种方式解决这个问题吗?

从 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 签名。

最新更新