Укажите получатель на лямбда-литерале без вывода типа - PullRequest
0 голосов
/ 12 сентября 2018

Предположим, я хочу лямбда-выражение типа Foo.()->Unit

Очевидно, что я могу указать это, полагаясь на вывод типа, так что лямбда захватывает тип получателя: val myLambda: Foo.()->Unit = { ... }

Моя интуиция заключалась в том, что я мог сделать что-то вроде: val myLambda = Foo.{ ... }

Но это не похоже на работу. Кажется странным, что я не могу выразить лямбда-значение определенного типа без зависимости от вывода типа из lhs.

Есть ли синтаксис, о котором я просто не знаю?

1 Ответ

0 голосов
/ 12 сентября 2018

Нет синтаксиса, который бы делал именно то, что вы ищете.Как вы уже изложили, вы можете создать лямбду с Foo в качестве получателя, либо создав ее, когда вы передаете ее в функцию, которая принимает такую ​​лямбду:

fun useFooExtension(fooExtension: Foo.() -> Unit) {
    fooExtension(Foo())
}

useFooExtension {
    println(this is Foo)
}

Или, указав тип переменной в явном виде, например, так:

var foo1: Foo.() -> Unit = { println(this is Foo) }

Однако вы можете объявить лямбду, которая принимает Foo в качестве первого параметра, с этим явным лямбдасинтаксис (тип переменной здесь только для пояснительных целей, в противном случае он избыточен и выводится):

var foo2: (Foo) -> Unit = { foo: Foo -> println(foo is Foo) }

И эти два типа лямбд на самом деле взаимно назначаются, потому что расширение на Foo действительно простопринимает Foo в качестве первого параметра под капотом.Таким образом, вы можете делать все эти вещи:

foo1 = foo2
foo2 = foo1

useFooExtension(foo1)
useFooExtension(foo2)

Существует одно различие между двумя типами: если вы хотите вызывать их с экземпляром Foo, вы можете вызывать только foo1 как расширение, но вы можете вызвать их оба, как если бы они взяли Foo в качестве первого параметра.Так что это все действительные звонки:

Foo().foo1()

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