所以我想创建一个实际发出元素的
Mono<Void>
(或任何Mono<SomeIgnorableType>
)。
为什么?因为我实际上想运行一个效果,而结果只是暗示效果已运行,但是,它可以忽略。
在 Haskell 中 Void 是一种不适宜居住的类型...就像 Scala 中的
Nothing
一样。在 Java 中,Void 也是不适宜居住的,但它的使用方式更像是 Scala 中的 Unit
类型或 Haskell 中的 ()
(0 元组)。只有一个居民的类型。
好吧,理论太多了。到目前为止我的选择:
Mono.just((Void) null)
抛出异常。
Mono.empty().single()
(因为我实际上想发出一个事件),当有人订阅它时,最终会失败。还有...
Mono.just("something").then()
运行效果,但是我无法将它与其他单声道链接,因为它只发出完整和错误事件。
那又怎样???
Java 缺乏空安全性意味着单元类型概念不能很好地翻译。当人们假设
Void
等同于单位类型时,我从未被说服。你永远无法通过设计来实例化它;您可以假设任何包含 Void
类型的引用都是 null
,我并不真正将其视为一个值 - 它更多的是缺乏任何值(即不适合居住的类型。)
我认为 Java 中没有内置任何“真正的”单元类型,但您可以通过使用具有单个值的
enum
轻松创建一个单元类型:
public enum Unit {UNIT}
如果您的
Mono
类型设置为 Unit
,这将满足您的需求 - 您可以不带值地完成 Mono
,也可以使用单个 Unit
值来完成它(并忽略该值,只是对其存在的事实做出反应),或者以错误完成它。听起来这正是您所追求的。
也就是说,直接回答问题并忽略你是否应该(恕我直言,你不应该),你可以模拟Void
来实际为其分配一个非空值。 Mockito 可以做到这一点,没有问题,你只需要确保
Mockito 已配置,以便它可以模拟最终类:
Void v = Mockito.mock(Void.class);
Mono.just(v)
.doOnNext(actualVoid -> System.out.println(actualVoid))
.block();
打印:
Mock for Void, hashCode: 1830745997
(这不是我曾经做过的事情,也不觉得有必要这样做,但这并不妨碍你在技术上做到这一点。)
var voidMono = Mono.fromRunnable(() -> {});
也许有一种更优雅的方式来做同样的事情,但现在就这样了。