Разница между kotlin также, применить, позволить, использовать, takeIf и takeUnless в Kotlin

Я прочитал много документов Kotlin об этих пунктах. Но я не могу понять так ясно.

Какая польза от Kotlin, позволяющеготакжевзять и взять в деталях?

Мне нужен пример каждого элемента. Пожалуйста, не размещайте документацию Kotlin. Мне нужен пример в реальном времени и варианты использования этих предметов.

2 ответа

Решение

позволять

public inline fun <T, R> T.let(block: (T) -> R): R = block(this)

Возьмите получатель и передайте его функции, переданной в качестве параметра. Вернуть результат функции.

val myVar = "hello!"
myVar.let { println(it) } // Output "hello!"

Ты можешь использовать let для нулевой проверки безопасности:

val myVar = if (Random().nextBoolean()) "hello!" else null
myVar?.let { println(it) } // Output "hello!" only if myVar is not null

также

public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }

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

Вы можете использовать это для выполнения чего-либо на объекте.

val person = Person().also {
  println("Person ${it.name} initialized!")
  // Do what you want here...
}

takeIf

public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null

Вернуть получатель, если функция (предикат) вернет true, иначе вернет null.

println(myVar.takeIf { it is Person } ?: "Not a person!")

takeUnless

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null

Такой же как takeIf, но с предикатом поменялся местами. Если true, вернуть null, иначе вернуть получателя.

println(myVar.takeUnless { it is Person } ?: "It's a person!")

Помогите

  • Вы можете легко использовать https://try.kotlinlang.org/ для тестирования. Вы можете найти примеры здесь.
  • Вы можете проверить исходный код стандартной библиотеки здесь. let, also, takeIf а также takeUnless здесь

пусть, также, apply, takeIf, takeUnless являются функциями расширения в Kotlin.

Чтобы понять эти функции, вы должны понимать функции расширения и лямбда-функции в Kotlin.

Функция расширения:

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

Kotlin, подобно C# и Gosu, предоставляет возможность расширять класс новыми функциями без необходимости наследования от класса или использования любого типа шаблона проектирования, такого как Decorator. Это делается с помощью специальных объявлений, называемых расширениями. Kotlin поддерживает функции расширения и свойства расширения.

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

fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())

Вы можете использовать вышеуказанную функцию расширения следующим образом:

val phoneNumber = "8899665544"
println(phoneNumber.isNumber)

который печатает true,

Лямбда-функции:

Лямбда-функции аналогичны интерфейсу в Java. Но в Kotlin лямбда-функции могут быть переданы в качестве параметра в функции.

Пример:

fun String.isNumber(block: () -> Unit): Boolean {
    return if (this.matches("[0-9]+".toRegex())) {
        block()
        true
    } else false
}

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

val phoneNumber = "8899665544"
    println(phoneNumber.isNumber {
        println("Block executed")
    })

Вышеуказанная функция будет печататься так,

Block executed
true

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

позволять

public inline fun <T, R> T.let(block: (T) -> R): R = block(this)

Два типа T и R используются в вышеуказанной функции.

T.let

T может быть любой объект, как класс String. так что вы можете вызывать эту функцию с любыми объектами.

block: (T) -> R

В параметре let вы можете увидеть вышеприведенную лямбда-функцию. Также вызывающий объект передается в качестве параметра функции. Таким образом, вы можете использовать вызывающий объект класса внутри функции. тогда он возвращает R (другой объект).

Пример:

val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }

В приведенном выше примере let принимает String в качестве параметра своей лямбда-функции и возвращает Pair в ответ.

Точно так же работает другая функция расширения.

также

public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }

функция расширения also принимает вызывающий класс в качестве параметра лямбда-функции и ничего не возвращает.

Пример:

val phoneNumber = "8899665544"
phoneNumber.also { number ->
    println(number.contains("8"))
    println(number.length)
 }

применять

public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }

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

Пример:

val phoneNumber = "8899665544"
phoneNumber.apply { 
    println(contains("8"))
    println(length)
 }

В приведенном выше примере вы можете видеть функции класса String, непосредственно вызываемые внутри функции lambda.

takeIf

public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null

Пример:

val phoneNumber = "8899665544"
val number = phoneNumber.takeIf { it.matches("[0-9]+".toRegex()) }

В приведенном выше примере number будет иметь строку phoneNumber только это соответствует regex, В противном случае это будет null,

takeUnless

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null

Это обратное восприятие.

Пример:

val phoneNumber = "8899665544"
val number = phoneNumber.takeUnless { it.matches("[0-9]+".toRegex()) }

number будет иметь строку phoneNumber только если не соответствует regex, В противном случае это будет null,

Другие вопросы по тегам