在Kotlin中getOrElseReturn的可能性

Sha*_*dov 1 java lambda java-8 kotlin

我经常有一个问题Optional和相似的类OptionTryEitherVAVR例如。

假设我有一些Optional,如果它为空,我想立即从一个方法中返回(无例外,因为我的方法Optional也在返回,所以getOrElseThrow不在图片之列),如果存在,我想进一步处理它。

public Optional<Integer> converter() {
  Optional<String> opt = getSomething();

  if(!opt.isPresent())
    return Optional.empty();

  String value = opt.get();  
  // some manipulations on value, such as map and flatMap would cause a huge mess
  return Integer.parseInt(value);  
}
Run Code Online (Sandbox Code Playgroud)

我只需要在值为空的情况下立即返回,就不能建立mapand的链flatMap。整个痛苦都在做.get()。有点像getOrElseThrow,但是用return代替throw会很棒- getOrElseReturn。显然在Java中是不可能的,因此我考虑在Kotlin中尝试此操作。

fun safeOptional(): Optional<Int> {
    val extracted = Optional.of("123")
            .getOrElseReturn { return Optional.empty() }

    val modified = extracted.toInt() * 2

    return Optional.of(modified)
}

private inline fun <T> Optional<T>.getOrElseReturn(block: (Optional<T>) -> T): T {
    return if (!this.isPresent)
        block(this)
    else
        this.get()
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,它实际上可以满足我的要求。如果更改为Optional.of("123")Optional.empty()则立即从方法返回。我不明白它是如何编译的。

我的方法需要一个block: (Optional<T>) -> T,否则将无法编译。因此,在我的情况下Optional<String>,我需要传递a block: (Optional<String>) -> String,但是,嘿-我所拥有的那个块与这个块相去甚远,并且仍然可以编译,如何?

当我将块提取到变量中时,它变成了val block: (Optional<String>) -> Nothing(我猜return语句是Nothing),并且仍在编译,这让我感到惊讶。

顺便说一句,我知道这段代码并不是我想要的-有人可以传递另一个块而无需非本地返回该方法,但是我认为没有另一种方法

Yas*_*jaj 5

将方法的第二部分提取到另一个私有方法中并调用 getSomething().map(this::otherPrivateMethod)

如果其中不存在任何值,则不会调用它 getSomething()

基本上,

public Optional<Integer> converter() {
    return getSomething().map(this::privateConverter); 
}

private Integer privateConverter(Integer integer) {
    // some manipulations on value, such as map and flatMap would cause a huge mess
    return Integer.parseInt(value);  
}
Run Code Online (Sandbox Code Playgroud)