如何创建一个真正发出元素的 Mono<Void>?

问题描述 投票:0回答:2

所以我想创建一个实际发出元素的

Mono<Void>
(或任何
Mono<SomeIgnorableType>
)。 为什么?因为我实际上想运行一个效果,而结果只是暗示效果已运行,但是,它可以忽略。

在 Haskell 中 Void 是一种不适宜居住的类型...就像 Scala 中的

Nothing
一样。在 Java 中,Void 也是不适宜居住的,但它的使用方式更像是 Scala 中的
Unit
类型或 Haskell 中的
()
(0 元组)。只有一个居民的类型。

好吧,理论太多了。到目前为止我的选择:

  1. Mono.just((Void) null)
    抛出异常。

  2. Mono.empty().single()
    (因为我实际上想发出一个事件),当有人订阅它时,最终会失败。还有...

  3. Mono.just("something").then()
    运行效果,但是我无法将它与其他单声道链接,因为它只发出完整和错误事件。

那又怎样???

project-reactor void
2个回答
3
投票

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

(这不是我曾经做过的事情,也不觉得有必要这样做,但这并不妨碍你在技术上做到这一点。)


0
投票

var voidMono = Mono.fromRunnable(() -> {});

也许有一种更优雅的方式来做同样的事情,但现在就这样了。

© www.soinside.com 2019 - 2024. All rights reserved.