let, also, apply, takeIf, takeUnless是Kotlin中的扩展函数.
要理解这些函数,你必须理解Kotlin中的Extension functions和Lambda functions.
Extension Function:个
By the use of extension function, we can create a function for a class without inheriting a class.
Kotlin, similar to C# and Gosu, provides the ability to extend a class
with new functionality without having to inherit from the class or use
any type of design pattern such as Decorator. This is done via special
declarations called extensions. Kotlin supports extension functions
and extension properties.
因此,要查找String
中是否只有数字,您可以创建如下所示的方法,而不继承String
类.
fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())
you can use the above extension function like this,
val phoneNumber = "8899665544"
println(phoneNumber.isNumber())
which is prints true
.
Lambda Functions:
Lambda函数就像Java中的接口(只包含一个方法.也称为单一抽象方法).Java 8中的Lambda也有Java版本.在Kotlin ,兰博达斯无处不在.大多数情况下,lambda在函数中作为参数传递.
例子:
fun String.isNumber(block: () -> Unit): Boolean {
return if (this.matches("[0-9]+".toRegex())) {
block()
true
} else false
}
You can see, the block is a lambda function and it is passed as a parameter. You can use the above function like this,
val phoneNumber = "8899665544"
phoneNumber.isNumber {
println("Block executed")
}
The above function will print like this,
Block executed
我希望,现在您对扩展函数和Lambda函数有了一个概念.现在我们可以逐个转到扩展函数.
let
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
Two Types T and R used in the above function.
T.let
T
could be any object like String, number, or any type. So you can invoke this function with any objects.
block: (T) -> R
You can see the lambda function In parameter of let the invoking object is passed as a parameter of the function. So you can use the invoking class object inside the function. then it returns the R
(another object).
例子:
val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }
In above example let takes String as a parameter of its lambda function and it returns Pair in return.
In the same way, other extension functions works.
also
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
extension function also
takes the invoking class as a lambda function parameter and returns nothing.
例子:
val phoneNumber = "8899665544"
phoneNumber.also { number ->
println(number.contains("8"))
println(number.length)
}
apply
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
与函数相同,但与函数传递的调用对象相同,因此可以使用函数和其他属性,而无需调用它或参数名.
例子:
val phoneNumber = "8899665544"
phoneNumber.apply {
println(contains("8"))
println(length)
}
You can see in the above example the functions of String class directly invoked inside the 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.takeUnless { it.matches("[0-9]+".toRegex()) }
number
will have a string of phoneNumber
only if not matches the regex
. Otherwise, it will be null
.