Функция расширения для универсального типа - PullRequest
0 голосов
/ 17 февраля 2019

Я новичок в Kotlin, и я пытаюсь понять псевдоним типа и функции.
У меня есть следующий пример:

interface EmptyInterface
typealias GenericCase<T> = T.(EmptyInterface) -> T

val myFunctionVariable: GenericCase<String> = {
    _ -> "Hello world!"
}

Насколько я понимаю, я расширяю то, что когда-либо T определяется функцией, которая принимает в качестве аргумента EmptyInterface и возвращает T.Так что myFunctionVariable - это функция, которая должна вызываться с передачей EmptyInterface

Но следующий код не компилируется

class a: EmptyInterface
println("${myFunctionVariable(a())}")  

Мне нужно передать String в качестве первогопараметр:

class a: EmptyInterface
println("${myFunctionVariable("",a())}")

Зачем нужна строка в качестве первого параметра?T.(EmptyInterface) -> T, в данном случае String.(EmptyInterface) -> String, имеет только 1 параметр.Может ли кто-нибудь объяснить это?

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

В типе T.(EmptyInterface) -> T первым T является получатель : экземпляр, к которому вызывается функция и который становится this в определении функции.(Аналогично функции расширения.)

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

Спецификация языка для нее здесь ;некоторые другие ответы также могут помочь.

0 голосов
/ 17 февраля 2019

T. в типе T.(EmptyInterface) -> T означает, что эта функция является функцией расширения для T.Поэтому обычным способом вызова этой функции является получение экземпляра T и вызов его в этом экземпляре, как если бы это была функция-член.В случае вашего примера, где вы выбрали T в качестве String, вы должны вызвать функцию для экземпляра String:

"foo".myFunctionVariable(a())

Синтаксис, который вы использовали, являетсяальтернативный способ вызвать это расширение, передавая получателю, как если бы он был первым параметром функции (который на уровне байт-кода действительно есть):

myFunctionVariable("foo", a())

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

...