ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## `takeIf` 与 `takeUnless` 除了作用域函数外,标准库还包含函数 `takeIf` 及 `takeUnless`。这俩函数使你可以将对象状态检查嵌入到调用链中。 当以提供的谓词在对象上进行调用时,若该对象与谓词匹配,则 `takeIf` 返回此对象。否则返回 `null`。因此,`takeIf` 是单个对象的过滤函数。反之,`takeUnless`如果不匹配谓词,则返回对象,如果匹配则返回 `null`。该对象作为 lambda 表达式参数(`it`)来访问。 ```kotlin import kotlin.random.* fun main() { //sampleStart val number = Random.nextInt(100) val evenOrNull = number.takeIf { it % 2 == 0 } val oddOrNull = number.takeUnless { it % 2 == 0 } println("even: $evenOrNull, odd: $oddOrNull") //sampleEnd } ``` 当在 `takeIf` 及 `takeUnless` 之后链式调用其他函数,不要忘记执行空检查或安全调用(`?.`),因为他们的返回值是可为空的。 ```kotlin fun main() { //sampleStart val str = "Hello" val caps = str.takeIf { it.isNotEmpty() }?.toUpperCase() //val caps = str.takeIf { it.isNotEmpty() }.toUpperCase() // 编译错误 println(caps) //sampleEnd } ``` `takeIf` 及 `takeUnless` 与作用域函数一起特别有用。 一个很好的例子是用 `let` 链接它们,以便在与给定谓词匹配的对象上运行代码块。 为此,请在对象上调用 `takeIf`,然后通过安全调用(`?.`)调用 `let`。对于与谓词不匹配的对象,`takeIf` 返回 `null`,并且不调用 `let`。 ```kotlin fun main() { //sampleStart fun displaySubstringPosition(input: String, sub: String) { input.indexOf(sub).takeIf { it >= 0 }?.let { println("The substring $sub is found in $input.") println("Its start position is $it.") } } displaySubstringPosition("010000011", "11") displaySubstringPosition("010000011", "12") //sampleEnd } ``` 没有标准库函数时,相同的函数看起来是这样的: ```kotlin fun main() { //sampleStart fun displaySubstringPosition(input: String, sub: String) { val index = input.indexOf(sub) if (index >= 0) { println("The substring $sub is found in $input.") println("Its start position is $index.") } } displaySubstringPosition("010000011", "11") displaySubstringPosition("010000011", "12") //sampleEnd } ```