Функции определения области видимости Kotlin: Android EditText поддерживает *apply *, *let * и * run *, но не * с*

#kotlin

#kotlin

Вопрос:

У меня есть действие, которое содержит EditText. Импортировано через:

 import kotlinx.android.synthetic.main.myActivity.*
 

Я хотел бы использовать эту with функцию, но по какой-то причине доступна только другая функция определения области видимости:

кроме того, отображаются apply, run, runCatching, takeIf и takeUnless, но не с

apply , also , run , runCatching , takeIf и takeUnless отображаются, но нет with (и да, я прокрутил дальше вниз и даже напечатал его. Он помечен как неизвестный, если я это сделаю).

Чтобы уточнить, что на самом деле происходит:

Неразрешенная ссылка: с

Существуют ли правила, когда объект имеет эти функции, а когда нет?

Ответ №1:

Это потому apply , also что , , run , runCatching , takeIf и takeUnless являются расширениями, когда with это функция с 2 параметрами. Вот хорошая статья об этом.

Вы можете использовать with вот так:

 with(editText) {
    //your code
}
 

Но вы не можете вызвать with , как вы пытались это сделать:

 editText.with() //compilation error
 

Обновить:
with цель функции — упростить вызов методов объекта, вам не нужно писать что-то подобное:

 someObject.a();
someObject.b();
someObject.c();
//etc
 

При использовании вы with можете написать это так:

 with(someObject) {
    a();
    b();
    c();
    //etc
}
 

Комментарии:

1. Я это понимаю. Меня смутило не то, как это вызвать, а тот факт, что я не мог его вызвать.

2. @Smogen вы можете назвать это так, как я написал выше. Я обновил ответ

3. Я приложил скриншот для уточнения

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

5. А, понял. Извините за путаницу.

Ответ №2:

Вы не получаете никаких предложений по поводу with function, потому что у него нет типа источника в качестве расширения, в то время как другие расширения содержат источник, прикрепленный к нему. Каким образом?

Посмотрите на разницу ниже :

с функцией

 @kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    ...
    return receiver.block()
}
 

пусть функционирует

 @kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    ...
    return block(this)
}
 

Вот T тип источника для расширения.