如何在 Kotlin 中组合可空值

How to compose nullables in Kotlin

假设您有 2 个返回可为空的函数,并且您无法组合这 2 个函数:

fun giveInt(x: Int):Int? = x+1
fun giveInt2(x: Int):Int? = x+2

为了实现组合,我写了这个函数:

fun all(x:Int):Int? {
  val y = giveInt(x)
  if (y != null) return giveInt2(y) else return null;
}

val four = all(1)

是否可以在不显式写入 if (y != null)return null 的情况下组合 2 个可空值以获得另一个可空值?

在 Scala 中我会做类似的事情:

def giveInt(x: Int):Option[Int] = Some(x+1)
def giveInt2(x: Int):Option[Int] = Some(x+2)
def all(x:Int): Option[Int] = giveInt(x).flatMap(giveInt2)

我应该使用 java Optional 来实现这个还是可以使用 ? 运算符?

谢谢:)

可以使用 safe call ?. 运算符和 let 函数组合,如下所示:

fun giveInt(x: Int):Int? = x+1
fun giveInt2(x: Int):Int? = x+2

fun all(x: Int): Int? = giveInt(x)?.let { giveInt2(it) }

如需更多此类成语,请使用this link

如果您想从字面上组合两个函数(在 FP 意义上),那么为了可读性,最好使用函数引用:

fun giveInt(x: Int):Int? = x+1
fun giveInt2(x: Int):Int? = x+2

fun all(x: Int): Int? = giveInt(x)?.let(::giveInt2)

当您只有两个可空值时,voddan 的答案是可以的,但在许多可空值或复杂的用例中不能很好地扩展。对于这些情况,存在 Konad 库来处理多个可空值,如下所示:

val foo: Int? = 1
val bar: String? = "2"
val baz: Float? = 3.0f

fun useThem(x: Int, y: String, z: Float): Int = x + y.toInt() + z.toInt()

val result: Int? = ::useThem.curry() 
   .on(foo.maybe) 
   .on(bar.maybe) 
   .on(baz.maybe)
   .nullable

如果你想保持它可以为空,或者

val result: Result<Int> = ::useThem.curry() 
   .on(foo.ifNull("Foo should not be null")) 
   .on(bar.ifNull("Bar should not be null")) 
   .on(baz.ifNull("Baz should not be null"))
   .result

如果你想累积错误。参见 maybe section