如何在 Kotlin 中惯用地测试非空、非空字符串?

How to idiomatically test for non-null, non-empty strings in Kotlin?

我是 Kotlin 的新手,我正在寻求帮助重写以下代码以使其更优雅。

var s: String? = "abc"
if (s != null && s.isNotEmpty()) {
    // Do something
}

如果我使用下面的代码:

if (s?.isNotEmpty()) {

编译器会抱怨

Required: Boolean
Found: Boolean?

谢谢。

您可以像这样使用 isNullOrEmpty or its friend isNullOrBlank

if(!s.isNullOrEmpty()){
    // s is not empty
}

isNullOrEmptyisNullOrBlank 都是 CharSequence? 上的扩展方法,因此您可以安全地将它们与 null 一起使用。或者像这样将 null 变成 false:

if(s?.isNotEmpty() ?: false){
    // s is not empty
}

您还可以执行以下操作

if(s?.isNotEmpty() == true){ 
    // s is not empty
}

虽然我非常喜欢@miensol 的回答,但我的回答是(这就是为什么我不把它放在评论中的原因):if (s != null && s.isNotEmpty()) { … } 实际上 Kotlin 中的惯用方式。只有这样,您才能在块内智能转换为 String,而按照接受的答案中的方式,您将不得不在块内使用 s!!

或者创建一个扩展方法并将其用作安全调用:

fun String?.emptyToNull(): String? {
    return if (this == null || this.isEmpty()) null else this
}

fun main(args: Array<String>) {
    val str1:String?=""
    val str2:String?=null
    val str3:String?="not empty & not null"

    println(str1.emptyToNull()?:"empty string")
    println(str2.emptyToNull()?:"null string")
    println(str3.emptyToNull()?:"will not print")
}

或者您可以创建一个 Extension Function:

public inline fun String?.ifNotEmpty(crossinline block: (String) -> Unit): Unit {
    if (this != null && this.isNotEmpty()) {
        block(this)
    }
}

See it in action

我发现这种方法在 Jetpack Compose 的上下文中更具可读性,这是一个 UI 工具包。

handles.twitter.ifNotEmpty {
    SocialMediaItem(handle = it, type = SocialMedia.TWITTER)
}

在这种情况下,如果 Twitter 句柄不为空且不是空字符串,则只显示 UI 的块。