Groovy 在 Java 上同时运行 map 和 orElseGet Optional

Groovy runs map and orElseGet on Java Optional at the same time

我遇到 Groovy 2.4.16 和 Java 8.0.212-zulujava.util.Optional 的奇怪行为。

所以,这是代码:

def optRegion = new HttpRegion(context).region()

optRegion.map{ region ->
    log.info("FOUND REGION: ${region} - ${optRegion}")
}.orElseGet{
    log.info("NO-REGION, JUST KIDDING! - ${optRegion}")
}

这些是日志:

2019-08-27 10:05:31.060 +0200 [vert.x-eventloop-thread-2] INFO  c.n.p.XXX:85 - FOUND REGION: POLAND - Optional[POLAND]
2019-08-27 10:05:31.061 +0200 [vert.x-eventloop-thread-2] INFO  c.n.p.XXX:87 - NO-REGION, JUST KIDDING! - Optional[POLAND]

我使用的是纯 Groovy class,没有 @CompileStatic 或任何其他注释。

HttpRegion returns 常规 java.util.Optional.

class HttpRegion {
  HttpRegion(RoutingContext context) {
      this.context = context
  }

  Optional<Region> region() {
      return java.util.Optional.of(...)
  }
}

任何人都可以向我解释哪里出了问题,以及为什么执行可选映射的两个分支?

Optional 上调用 map map 返回的值替换 可选内容。

一个groovy闭包总是returns一个值。

在本例中,它是 null 值,这就是为什么 Optional 在调用 map

后变为空的原因
optRegion.map{ region ->
    log.info("FOUND REGION: ${region} - ${optRegion}")
}.orElseGet{
    log.info("NO-REGION, JUST KIDDING! - ${optRegion}")
}

如果你把它分成两部分,你会看到这个 returns null :

map{ region ->
    log.info("FOUND REGION: ${region} - ${optRegion}")
}

然后调用这个闭包,因为你有 null。

orElseGet{
    log.info("NO-REGION, JUST KIDDING! - ${optRegion}")
}

如果您将 map 更改为:

map{ region ->
    log.info("FOUND REGION: ${region} - ${optRegion}")
    return region
}

那么你应该有一个日志语句。