用于处理非空对象和非空字符串表示的Kotlin成语

我有一个空的属性(一个Java对象),知道如何将自己转换为一个字符串,如果这种表示不是空的,我想做一些事情。 在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 ,可以把它缩短到稍微短一些。

步骤是:

  1. 如果对象(A)不为空
  2. 如果对象(A)的字符串表示(B)不是空白的
  3. (B)

我试过了:

  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 ,我不太在意这一点。

这里有什么“Kotlin的方式”?

您可以使用(自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安全访问者和其他时间不。 这是因为某些函数的预测/ lambda表达式可以使用空值,而其他函数则不能。 你可以设计这些你想要的方式。 随你便!

有关此主题的更多信息,请参阅: 处理空字符的习惯方法

Interesting Posts