Kotlin: разница между ИТ и ЭТИМ ключевым словом - PullRequest
2 голосов
/ 02 марта 2020

В одном из kotlin интервью кто-то спросил меня разницу между it & this ключевыми словами.

У меня есть поиск в Google, но я не могу найти правильный ответ на вопрос.

Может кто-нибудь подсказать мне, какова разница между этими двумя?

Я знаю это очень простой c вопрос, я новичок в kotlin.

Ответы [ 4 ]

3 голосов
/ 02 марта 2020

it относится только к лямбде с одним параметром. Это имя по умолчанию для одного параметра и сокращение, которое позволяет вам не указывать имя отдельного параметра. Функция, объявленная таким образом, может выглядеть следующим образом:

(String) -> Unit

В лямбда-выражении this является аргументом получателя. Это работает, только если функция определена как имеющая получателя, например:

String.() -> Unit

Если в объявлении функции нет получателя, this имеет то же значение, что и вне области лямбды , Для функции расширения это приемник функции расширения. В противном случае это класс, содержащий функцию.

2 голосов
/ 02 марта 2020

Разницу между it & этим ключевыми словами можно объяснить на примере приемников лямбда-метода (он же функции высшего порядка) .

Допустим, вы написали функцию или используете функцию, которая обеспечивает обратный вызов в качестве приемника лямбда-метода. Примерно так: () -> Unit

Итак, есть две возможности, которыми вы хотите, чтобы ваш обратный вызов был:

  1. Предоставление параметра к обратному вызову

    • Параметр с помощью обратного вызова означает, что вы хотите дать вашему обратному вызову параметр, который вызывающий абонент может использовать во время вызова, также рассматриваемый как it .

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

Посмотрите фрагмент ниже:

fun someMethodWithCallback(callback: (Int) -> Unit) {
    callback(0)
}

// On the time of consumption, the `Int` parameter by default exposed to callback as it parameter.
obj.someMethodWithCallback { it -> // Here it is the method parameter of callback that we passed, you can also rename it to any other named value
    // it can be directly used as Int value if needed or you can rename it at receiver above
}

Примечание: вы можете предоставить несколько параметров для обратного вызова, а затем вы не сможет получить it , скорее обратный вызов предоставит вам количество переданных переменных.

Предоставление объекта для обратного вызова

  • Другим способом обеспечения обратного вызова является предоставление самого объекта в качестве параметра обратного вызова. Это означает, что синтаксис обратного вызова слегка изменяется и дает вам сам объект в качестве параметра обратного вызова this .

Все, что написано выше, просто означает: Int.() -> Unit . этот объект функционального метода может дать вам целое число во время вызова.

Проверьте фрагмент ниже:

fun someMethodWithCallback(callback: Int.() -> Unit) {
    callback(0)
}

// On the time of consumption, the `Int` parameter by default exposed to callback as it parameter.
obj.someMethodWithCallback { this // Here this is the method object of callback that we passed, you can not rename it to anything else
    // it can be used as Int value by referencing as this
}

Надеюсь, что это имеет смысл!

2 голосов
/ 02 марта 2020

Вам необходимо знать о функциях области действия :

Стандартная библиотека Kotlin содержит несколько функций, единственная цель которых - выполнить блок кода в контексте объект. Когда вы вызываете такую ​​функцию для объекта с предоставленным лямбда-выражением, он формирует временную область.

Внутри этой области есть объект Context либо this, либо it

В функциях Scope run, apply и with область действия (временно) изменяется на область объекта, для которого вызывается эта функция:

val str = "Hello"
str.run {
    //Here this refers to str
}

В функциях Scope let, also область действия не изменяется (остается такой же, как область действия вызывающего абонента), но ваша лямбда получит контекст как it внутри лямбды:

val str = "Hello"
str.let {
    //Here it refers to str
}

You можете проверить ссылки для получения дополнительной информации.

0 голосов
/ 02 марта 2020

Я бы хотел go экстремальный фундамент без всяких причудливых слов. это ключевое слово Когда у вас есть один параметр, вы можете вызывать его, используя ключевое слово it , и это хорошо работает, например, с HOF,

 private fun itKeyword(itKeyword:(String) -> Unit) {
        itKeyword("")
    }

    fun callItFun() {
        itKeyword {//it:String // this is high light over here like this

        }

Но если вы попытаетесь сделать что-то вроде этого:

private fun itKeyword(itKeyword:(String, Int) -> Unit) {
        itKeyword("", 1)
    }

    fun callItFun() {
        itKeyword {yourName, age -> //yourName, age is define by user
        }
   }

видите? здесь нет ключевого слова it , определяемого здесь компилятором, но вместо этого мы должны передать два параметра, когда мы определили HOF, но если мы оставим это поле пустым, компилятор выдаст нам ошибку Эй, передайте что-нибудь, чувак, я о какой переменной вы говорите, здесь переданы две переменные. Это означает, что когда у вас есть только один параметр, вы можете вызвать его, используя ключевое слово it . это ключевое слово Существуют две области видимости или переменные / свойства: глобальная и локальная область видимости, когда вы определили некоторую переменную как глобальную область видимости и хотите вызвать ее в нескольких методах / функциях, и в некотором месте вы должны использовать тот же тип другой переменной с тем же именем. на местном уровне, в этом случае мы будем использовать это ключевое слово, и почему это так?

private lateinit var mContext: Context

    fun thisKeyword(mContext: Context) {
        this.mContext = mContext
    }

но что, если мы не используем это ключевое слово и сохраняем его так:

private lateinit var mContext: Context
    fun thisKeyword(mContext: Context) {
        mContext = mContext
    }

Компилятор скажет: мах, что ты наделал, не позвонил мне в голову JK, Компилятор скажет, Val не может быть переназначен , чего ждать? мы не инициировали его как val, но если мы увидим в глобальном масштабе, мы инициируем его как var, но угадайте, что? компилировать правильно. В Kotlin при передаче чего-либо в параметр функции они действуют как Val по умолчанию , что означает, что без этот компилятор использовал локальные переменные области видимости, а не глобальную область видимости, но когда мы используем , это ключевое слово, которое мы сообщаем компилятору, с ключевым словом это свойство здесь до = является глобальной областью действия this.mContext , а после = является локальным, поэтому мы используем это ключевое слово для воздерживается от переменного конфликта. надеюсь, это поможет, спасибо (*).

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