我有一个可以为null的属性(一个Java对象)知道如何将自己转换为String,如果这个表示不为空,我想用它做一些事情。在Java中,这看起来像:
MyObject obj = ...
if (obj != null) {
String representation = obj.toString();
if (!StringUtils.isBlank(representation)) {
doSomethingWith(representation);
}
}
我试图找到将此转换为Kotlin的最惯用的方式,我有:
with(obj?.toString()) {
if (!isNullOrBlank()) {
doSomethingWith(representation)
}
}
但对于这么简单的操作来说,它仍然感觉太多了。我有这样的感觉,即let
,when
和with
合并后,我可以将其缩小到更短的时间。
步骤如下:
我试过了:
when(where?.toString()) {
isNullOrBlank() -> builder.append(this)
}
但是(1)它失败了:
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: @InlineOnly public inline fun
CharSequence?.isNullOrBlank(): Boolean defined in kotlin.text @InlineOnly public inline fun CharSequence?.isNullOrBlank(): Boolean defined in
kotlin.text
即使它已经过去了,(2)它也会想要详尽无遗的else
,我并不是真正关心的。{/ p>
" Kotlin方式"这里吗
答案 0 :(得分:13)
您可以使用(自Kotlin 1.1开始)内置的stdlib takeIf()
或takeUnless
扩展程序,可以使用:
obj?.toString().takeUnless { it.isNullOrBlank() }?.let { doSomethingWith(it) }
// or
obj?.toString()?.takeIf { it.isNotBlank() }?.let { doSomethingWith(it) }
// or use a function reference
obj?.toString().takeUnless { it.isNullOrBlank() }?.let(::doSomethingWith)
为了对最终值执行操作doSomethingWith()
,您可以使用apply()
在当前对象的上下文中工作,返回是同一个对象,或者let()
来更改表达式的结果,或run()
在当前对象的上下文中工作,并且还更改表达式的结果,或also()
在返回原始对象时执行代码。
如果您希望命名更有意义,也可以创建自己的扩展功能,例如nullIfBlank()
可能是一个好名字:
obj?.toString().nullIfBlank()?.also { doSomethingWith(it) }
这被定义为可空String
的扩展名:
fun String?.nullIfBlank(): String? = if (isNullOrBlank()) null else this
如果我们再添加一个扩展名:
fun <R> String.whenNotNullOrBlank(block: (String)->R): R? = this.nullIfBlank()?.let(block)
这允许将代码简化为:
obj?.toString()?.whenNotNullOrBlank { doSomethingWith(it) }
// or with a function reference
obj?.toString()?.whenNotNullOrBlank(::doSomethingWith)
您始终可以编写这样的扩展名,以提高代码的可读性。
注意:有时我使用?.
null安全访问器,有时则不使用。{1}} null安全访问器。这是因为某些函数的predicat / lambdas使用可空值,而其他函数则没有。您可以按照自己的方式设计这些。这取决于你!
有关此主题的更多信息,请参阅:Idiomatic way to deal with nullables