我阅读了许多关于这些项目的 Kotlin 文档。但我不能理解得这么清楚。
Kotlin let , also , takeIf和takeUnless的详细用途是什么?
我需要每个项目的示例。请不要发布 Kotlin 文档。我需要这些项目的实时示例和用例。
我阅读了许多关于这些项目的 Kotlin 文档。但我不能理解得这么清楚。
Kotlin let , also , 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...
}
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!")
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
与 相同takeIf
,但谓词颠倒。如果为真,则返回 null,否则返回接收者。
println(myVar.takeUnless { it is Person } ?: "It's a person!")
let
, also
,takeIf
和takeUnless
这里。let、also、apply、takeIf、takeUnless是 Kotlin 中的扩展函数。
要了解这些函数,您必须了解Kotlin 中的扩展函数和Lambda 函数。
扩展功能:
通过使用扩展函数,我们可以在不继承类的情况下为类创建函数。
Kotlin 与 C# 和 Gosu 类似,提供了使用新功能扩展类的能力,而无需从类继承或使用任何类型的设计模式,例如装饰器。这是通过称为扩展的特殊声明完成的。Kotlin 支持扩展函数和扩展属性。
因此,要查找 中是否只有数字,您可以在不继承类String
的情况下创建如下所示的方法。String
fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())
您可以像这样使用上述扩展功能,
val phoneNumber = "8899665544"
println(phoneNumber.isNumber())
这是打印true
。
Lambda 函数:
Lambda 函数就像 Java 中的接口(仅包含一个方法。也称为单一抽象方法)。从 Java 8 开始,lambda 也可以在 java 中使用。在 Kotlin 中,到处都使用 lambda。大多数情况下,lambdas 作为函数中的参数传递。
例子:
fun String.isNumber(block: () -> Unit): Boolean {
return if (this.matches("[0-9]+".toRegex())) {
block()
true
} else false
}
您可以看到,该块是一个 lambda 函数,它作为参数传递。您可以像这样使用上述功能,
val phoneNumber = "8899665544"
phoneNumber.isNumber {
println("Block executed")
}
上面的函数会这样打印,
Block executed
我希望,现在您对扩展函数和 Lambda 函数有所了解。现在我们可以一一进入扩展功能。
让
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
上述函数中使用了两种类型 T 和 R。
T.let
T
可以是任何对象,如字符串、数字或任何类型。因此,您可以使用任何对象调用此函数。
block: (T) -> R
可以看到 lambda 函数的 In 参数让调用对象作为函数的参数传递。所以你可以在函数内部使用调用类对象。然后它返回R
(另一个对象)。
例子:
val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }
在上面的示例中,let 将String作为其 lambda 函数的参数,并返回Pair作为回报。
以同样的方式,其他扩展功能也起作用。
还
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
扩展函数also
将调用类作为 lambda 函数参数并且不返回任何内容。
例子:
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)
}
您可以在上面的示例中看到直接在 lambda 函数内部调用的 String 类的函数。
采取如果
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
。
除非
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
它与 takeIf 正好相反。
例子:
val phoneNumber = "8899665544"
val number = phoneNumber.takeUnless { it.matches("[0-9]+".toRegex()) }
number
phoneNumber
只有不匹配时才会有一个字符串regex
。否则,它将是null
。