我想要像以下一样applyif工作:
builder.applyif(<condition expression>) {
builder.set...
}
Run Code Online (Sandbox Code Playgroud)
等于:
builder.apply {
if (<condition expression>) {
builder.set...
}
}
Run Code Online (Sandbox Code Playgroud)
那可能吗?
当然是.你几乎可以编程任何东西,但不要重新发明轮子.查看答案的底部,看看没有自己的扩展功能的标准Kotlin方法,这可能已经满足您的需求(不完全如此applyIf).
但是,现在让我们看看如何applyIf实现:
inline fun <T> T.applyIf(predicate: T.() -> Boolean, block: T.() -> Unit): T = apply {
if (predicate(this))
block(this)
}
Run Code Online (Sandbox Code Playgroud)
inline如果您正在使用lambdas实现扩展功能,请不要忘记.
以下是上述示例用法.
// 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)
}
Run Code Online (Sandbox Code Playgroud)
如果您只想提供布尔值,可以使用以下扩展函数:
inline fun <T> T.applyIf(condition : Boolean, block : T.() -> Unit) : T = apply {
if(condition) block(this)
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
val someCondition = true
ADemo().applyIf(someCondition) {
println(this)
}
Run Code Online (Sandbox Code Playgroud)
现在可以用更多人熟悉的Kotlin标准方式:
ADemo().takeIf(ADemo::isTrue)
?.apply(::println)
// or
ADemo().takeIf { it.isTrue() }
?.apply { println(this) }
Run Code Online (Sandbox Code Playgroud)
如果他们确实记得(我实际上没有看到Marko Topolniks评论),他们应该立即知道发生了什么.但是,如果您ADemo()在调用takeIf此方法后需要给定值(即),则可能对您不起作用,因为以下将变量设置为null:
val x = ADemo().takeIf { false }
?.apply { println(this) /* never called */ }
// now x = null
Run Code Online (Sandbox Code Playgroud)
而以下将宁愿将变量设置为ADemo-instance:
val x = ADemo().applyIf(false) { println(this) /* also not called */ }
// now x contains the ADemo()-instance
Run Code Online (Sandbox Code Playgroud)
链接构建器调用可能不是那么好.你仍然可以通过标准科特林功能相结合,还做到这一点takeIf有apply或also(或者with,let,run,这取决于你是否想返回的东西或者不是,或者您喜欢与工作it或this):
val x = builder.apply {
takeIf { false }
?.apply(::println) // not called
takeIf { true }
?.apply(::println) // called
}
// x contains the builder
Run Code Online (Sandbox Code Playgroud)
但是,我们几乎就在那里,你已经在你的问题中.使用applyIf-usage 同样看起来更好看:
val x = builder.applyIf(false, ::println) // not called
.applyIf(true) {
println(this) // called
}
// x contains the builder
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
491 次 |
| 最近记录: |