пусть, также, применять, takeIf, takeUnless в Котлине

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

Какая польза от Котлина, пусть также , возьмет и не возьмет без подробностей?

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

позволять

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 }

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

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

 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, else верните ресивер .

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

Помогите

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

let, также, apply, takeIf, takeUnless – это функции расширения в Котлине.

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

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

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

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

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

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

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

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

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

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

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

Пример:

 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 

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

позволять

 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 { number -> println(contains("8")) println(length) } 

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

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 

Это противоположность takeIf.

Пример:

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

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