【问题标题】:Kotlin equivalent of Optional.map and a method referenceKotlin 等效于 Optional.map 和方法参考
【发布时间】:2017-06-06 03:35:27
【问题描述】:

Java

考虑以下 Java:

private void example() {
  Optional<String> foo = ...
  Optional<String> bar = 
      foo.map(this::transform1)
          .map(this::transform2)
}

private String transform1(String s) {
  return s + "!";
}

private String transform2(String s) {
  return "@" + s;
}

请注意,transform 方法接受非可选值。

问题

Kotlin 是否有一个内置机制来在使用它的可空/非空类型时实现相同的目标?

第一次尝试

我设法通过以下方式实现了这种效果:

fun <A, B> nullMap(a: A?, mapper: (a: A) -> B?): B? =
  if (a != null) mapper.invoke(a) else null

fun example() {
  val foo: String? = "Space cookies"
  val bar1: String? = nullMap(foo, Example::transform1)
  val bar2: String? = nullMap(bar1, Example::transform2)
}

fun transform(s: String) = s + "!"
fun transform2(s: String) = "@" + s

(同样,我们注意到对于 transform 方法,s 是一个不可为空的字符串。)

所以,我的问题以另一种方式表述:在 Kotlin 的标准库中是否已经存在 nullMap 等效项?和/或:有不同的标准方法吗?

最后,能否在 Kotlin 中实现视觉上更简洁的 chaining 方法,而不是单独的赋值(上图)或嵌套的函数调用?有一刻我认为你可以在Any 上添加nullMap 作为扩展方法,但有时你尝试调用方法的接收器是null(这样就行不通了)。

【问题讨论】:

  • 应该指出,断言sometimes the receiver you're trying to invoke a method on is null (so that won't work). 不正确——你可以在可空类型上有一个扩展函数,接收者为空也没有问题。

标签: kotlin


【解决方案1】:

我们使用safe call operator:

val foo: Foo? = ...
foo?.toA()?.toB()

或者

foo?.let(this::transform1)?.let(this::transform2)

Kotlin 强调 null 安全性。其手册中有an entire chapter描述相关技术。

【讨论】:

  • 我正在寻找 let,谢谢。我知道 null 安全运算符。
  • Kotlin 有很多这样的函数,比如letapplyrunalsousewith。只需提及它们,这样您就不会在寻找另一个时迷失方向。
  • 感谢@glee8e - 我将不得不花一些时间阅读standard library
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
相关资源
最近更新 更多