kotlin also, apply, let, use, takeIf 和 takeUnless 在 Kotlin 中的区别
difference between kotlin also, apply, let, use, takeIf and takeUnless in Kotlin
我阅读了很多关于这些项目的 Kotlin 文档。但是我理解的不是很清楚。
Kotlin有什么用 let, also, takeIf and takeUnless详细?
我需要每个项目的示例。请不要 post Kotlin 文档。我需要这些项目的实时示例和用例。
让
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
获取接收器并将其传递给作为参数传递的函数。 Return 函数的结果。
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 作为参数和 return receiver.
传递的函数
就像 let 但总是 return 接收者 ,而不是函数的结果。
您可以使用它对对象进行操作。
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
Return receiver if the function (predicate) return true, else return 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
相同,但谓词相反。如果为真,return 为空,否则 return 接收者 .
println(myVar.takeUnless { it is Person } ?: "It's a person!")
帮助
- 您可以使用https://try.kotlinlang.org/ for testing easily. You can find examples here。
- 您可以查看标准库的源代码here.
let
, also
, takeIf
and takeUnless
here。
let, also, apply, takeIf, takeUnless 是 Kotlin 中的扩展函数。
要了解这些函数,您必须了解 Kotlin 中的扩展函数和Lambda 函数。
扩展函数:
通过使用扩展函数,我们可以在不继承class的情况下为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
class.
fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())
可以这样使用上面的扩展函数,
val phoneNumber = "8899665544"
println(phoneNumber.isNumber())
这是打印 true
.
Lambda 函数:
Lambda函数就像Java中的接口(只包含一个方法。也称为单一抽象方法)。从 Java 开始,java 中也提供了 8 个 lambda。在 Kotlin 中,lambda 无处不在。大多数 lambda 表达式作为函数中的参数传递。
示例:
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 函数在 let 的参数中将调用对象作为函数的参数传递。所以你可以在函数内部使用调用 class 对象。然后它 return 是 R
(另一个对象)。
示例:
val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }
在上面的例子中,let 将 String 作为其 lambda 函数的参数,它 returns Pair in return.
其他扩展功能同理
还有
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
扩展函数 also
将调用 class 作为 lambda 函数参数,return 什么都没有。
示例:
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 class 的函数。
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
.
取除非
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
只有在不匹配 regex
时才会有一个 phoneNumber
的字符串。否则,它将是 null
.
我阅读了很多关于这些项目的 Kotlin 文档。但是我理解的不是很清楚。
Kotlin有什么用 let, also, takeIf and takeUnless详细?
我需要每个项目的示例。请不要 post Kotlin 文档。我需要这些项目的实时示例和用例。
让
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
获取接收器并将其传递给作为参数传递的函数。 Return 函数的结果。
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 作为参数和 return receiver.
传递的函数
就像 let 但总是 return 接收者 ,而不是函数的结果。
您可以使用它对对象进行操作。
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
Return receiver if the function (predicate) return true, else return 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
相同,但谓词相反。如果为真,return 为空,否则 return 接收者 .
println(myVar.takeUnless { it is Person } ?: "It's a person!")
帮助
- 您可以使用https://try.kotlinlang.org/ for testing easily. You can find examples here。
- 您可以查看标准库的源代码here.
let
,also
,takeIf
andtakeUnless
here。
let, also, apply, takeIf, takeUnless 是 Kotlin 中的扩展函数。
要了解这些函数,您必须了解 Kotlin 中的扩展函数和Lambda 函数。
扩展函数:
通过使用扩展函数,我们可以在不继承class的情况下为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
class.
fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())
可以这样使用上面的扩展函数,
val phoneNumber = "8899665544"
println(phoneNumber.isNumber())
这是打印 true
.
Lambda 函数:
Lambda函数就像Java中的接口(只包含一个方法。也称为单一抽象方法)。从 Java 开始,java 中也提供了 8 个 lambda。在 Kotlin 中,lambda 无处不在。大多数 lambda 表达式作为函数中的参数传递。
示例:
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 函数在 let 的参数中将调用对象作为函数的参数传递。所以你可以在函数内部使用调用 class 对象。然后它 return 是 R
(另一个对象)。
示例:
val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }
在上面的例子中,let 将 String 作为其 lambda 函数的参数,它 returns Pair in return.
其他扩展功能同理
还有
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
扩展函数 also
将调用 class 作为 lambda 函数参数,return 什么都没有。
示例:
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 class 的函数。
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
.
取除非
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
只有在不匹配 regex
时才会有一个 phoneNumber
的字符串。否则,它将是 null
.