inline fun <T> T.applyIf(predicate: T.() -> Boolean, block: T.() -> Unit): T = apply {
if (predicate(this))
block(this)
}
如果你用lambdas实现扩展函数,请不要忘记inline。 下面是上面的示例用法。
// sample class
class ADemo {
fun isTrue() = true
}
// sample usage using method references
ADemo().applyIf(ADemo::isTrue, ::println)
// or if you prefer or require it, here without
ADemo().applyIf( { isTrue() } ) {
println(this)
}
如果你只想提供一个布尔值,你可以使用下面的扩展函数:
inline fun <T> T.applyIf(condition : Boolean, block : T.() -> Unit) : T = apply {
if(condition) block(this)
}
并调用它:
val someCondition = true
ADemo().applyIf(someCondition) {
println(this)
}
fun <T> T.applyIf(condition: Boolean, block: T.() -> T) = if (condition) block() else this
fun main() {
println("a".applyIf(true) { uppercase() }) // A
println("a".applyIf(false) { uppercase() }) // a
}
4条答案
按热度按时间ca1c2owp1#
是的,当然。你几乎可以编程任何东西,但不要重新发明轮子。看看答案的底部,可以看到一个没有自己的扩展函数的标准Kotlin方法,它可能已经满足了你的需求(虽然不完全是
applyIf
)。现在,让我们看看如何实现
applyIf
:如果你用lambdas实现扩展函数,请不要忘记
inline
。下面是上面的示例用法。
如果你只想提供一个布尔值,你可以使用下面的扩展函数:
并调用它:
现在有一个可能的Kotlin标准方式,让更多的人熟悉:
如果他们真的记得(实际上我直到看到Marko Topolniks的评论才记得),他们应该立即知道发生了什么。但是,如果您需要给定的值(即例如
ADemo()
)在调用takeIf
之后,这种方法可能不适用于您,因为下面将把变量设置为null
:而下面的代码会将变量设置为
ADemo
-instance:那么链接构建器调用可能就不那么好了。你也可以通过标准的Kotlin函数来完成这个任务,方法是将
takeIf
与apply
或also
(或者with
,let
,run
,取决于你是否想要返回某些东西,或者你更喜欢使用it
或this
)组合在一起:但话又说回来,我们几乎在你已经在你的问题。使用
applyIf
的效果肯定更好:ki0zmccv2#
当然可以,你只需要一个扩展函数,这样你就可以在
builder
上调用它,你需要它接受Boolean
参数和lambda来执行。如果你看一下
apply
函数本身的源代码,它将有助于大部分实现:基于此,
applyIf
可以简单地为:用法如下:
dauxcl2d3#
owfi6suc4#
一个不可变的值(e。例如,Compose
Modifier
)如果apply
不起作用,则必须显式返回this
,类似于以下内容