Устранение неоднозначности разрешения перегрузки - PullRequest
0 голосов
/ 06 марта 2019

Я не понимаю, почему следующие две 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)

Можно ли как-то решить эту проблему?

1 Ответ

2 голосов
/ 06 марта 2019

Функции с точки зрения JVM имеют тот же тип после стирания типа, это будет что-то вроде (в Java):

public void into(Boo boo, Fucntion1 block);

Тип возврата функции не учитывается для такого разрешенияна уровне JVM.

Используйте аннотацию @JvmName("unique name") с различными параметрами для каждого из методов, чтобы попросить компилятор Kotlin сгенерировать уникальные имена для методов на уровне JVM.

UPD : вам не нужны общие параметры для этих функций, а именно <Fiz> и <Foo>.Вы не используете их в объявлениях, и компилятор Kotlin также не может определить типы

UPD2 : компилятор не сможет угадать тип лямбда, который вы вызываете, поэтому выможет потребоваться также явно указать его тип, например

val builder : FizMorphBuilder.() -> Unit = { /*the builder lambda */ }
val z = Boo().into(builder)

Мы используем объявление с явным типом, чтобы объяснить, какая точная лямбда-сигнатура компоновщика нам нужна в этот момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...