Генератор последовательности как вызов функции расширения терпит неудачу с " несоответствием типа приемника"


Я играю с попыткой сгенерировать последовательность из одного значения 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) Котлин: неразрешенная ссылка. Ни один из следующих кандидатов не применим из-за несоответствия типа приемника: общественный инфикс весело Длинный.join (R: LongRange): последовательность, определенная в main.Котлин

Похоже, что компилятор распознает, что сигнатура функцииблизка к тому, что я пытаюсь достичь, но я явно не понимаю, что означает "несоответствие типа приемника".

1 4

1 ответ:

Ошибка "несоответствие типа приемника" означает, что то, чтопередается в качестве приемника функции расширения (т. е. то, что она вызывается), не соответствует объявленному типу приемника.

Котлин, в отличие от Явы, не продвигает числа к более широким числовым типам, и вы должны использовать Long литералы в коде, где ожидается 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