我读了很多关于这些物品的Kotlin文件。但我无法理解这一点。
Kotlin 让,还, takeIf 和 takeUnless 有什么用?
我需要每个项目的示例。请不要发布Kotlin文档。我需要一个实时示例并使用这些项目的案例。
答案 0 :(得分:32)
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 }
执行以 receiver 作为参数传递的函数并返回接收器。
它就像让但总是返回接收器,而不是函数的结果。
您可以使用它在对象上做某事。
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,则返回 receiver ,否则返回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
相同,但谓词相反。如果为true,则返回null,否则返回 receiver 。
println(myVar.takeUnless { it is Person } ?: "It's a person!")
let
,also
,takeIf
和takeUnless
here。答案 1 :(得分:11)
让,也,申请,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中的Interface。但是在Kotlin中,lambda函数可以作为函数中的参数传递。
示例:
fun String.isNumber(block: () -> Unit): Boolean {
return if (this.matches("[0-9]+".toRegex())) {
block()
true
} else false
}
你可以看到,该块是一个lambda函数,它作为参数传递。你可以使用上面这样的函数,
val phoneNumber = "8899665544"
println(phoneNumber.isNumber {
println("Block executed")
})
上面的功能会像这样打印,
Block executed
true
我希望,现在你对扩展函数和Lambda函数有所了解。现在我们可以逐个转到扩展功能。
可让强>
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
上述功能中使用了两种类型T和R.
T.let
T
可以是String类之类的任何对象。所以你可以用任何对象调用这个函数。
block: (T) -> R
在let的参数中,您可以看到上面的lambda函数。此外,调用对象作为函数的参数传递。因此,您可以在函数内部使用调用类对象。然后它返回R
(另一个对象)。
示例:
val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }
在上面的示例中,我们将 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类的函数。
<强> 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.takeUnless { it.matches("[0-9]+".toRegex()) }
仅当number
与phoneNumber
不匹配时, regex
才会有null
字符串。否则,它将是_.flattenDeep(temp1);
。