本文已参与「新人创作礼」活动,一起开启掘金创作之路。
What's Optional?
Optional是一个容器对象, 用于包含非空对象. Optional对象不包含值时表示的是null. 与检测null值相反, 该对象有不同的工具方法用于促进代码来处理"可用"和"不可用"的值. Optional在 Java 8 中首次引入, 且与 Guava 中的Optional相似.
Java Optional API
Optional的工具方法有:
static <T> Optional<T> empty(): 提供空的Optional实例.static <T> Optional<T> of(T value): 提供包含非null值的Optional实例.static <T> Optional<T> ofNullable(T value):value为非null时, 作用等同于of(T value), 而value为null时, 作用等同于empty().
更多请查看
What's Koptional
Koptional是Kotlin版本的简约Optional类型.
Kotlin本身并不需要Optional类型, 因为它有强空安全系统, 该系统事实上终止了这种封装的需求. 然而有一些Java API和库, 像RxJava 2和RxJava 3, 并不接受null值, Kotlin语言层面的可空性对此无能为力.
在许多场景下, 可以通过sealed class来表示空值. 然而在一些简单的场景下, 比如在RxJava流中传递String?, Optional是更方便的解决方案.
Koptional的目的是为了使用和适配Kotlin的空安全更加地方便, 由此引起:
- 只有2个函数:
toOptional()和toNullable(). -
- 模拟了类似于
toInt()和toBoolean()的函数.
- 模拟了类似于
Some和None被声明为顶级类型.-
- 不需要写
Optional.Some和Optional.None.
- 不需要写
- 没有
map(),getOrElse(),filter()等函数. -
- 使用
toNullable()和Kotlin标准库函数, 如let,takeIf等.
- 使用
Usage
创建
val some = Some(value)
val none = None // It's an object!
转化
// T? → Optional<T>
// If value is null — you'll get None, otherwise you'll get Some(value).
val o = value.toOptional()
// Optional<T> → T?
// If optional is None — you'll get null, otherwise you'll get non-null T value.
val t = optional.toNullable()
充分利用Kotlin的特性
回退到None (类似于java.util.Optional.getOrElse()函数)
val f = optional.toNullable() ?: "fallback"
智能类型转换
when (optional) {
is Some -> println(optional.value)
is None -> println("Nope!")
}
解构
// If Optional is None — you'll get null, otherwise you'll get non-null T value.
val (value) = optional
与Java的交互访问
使用静态方法Optional.toOptional()将T类型实例封闭进Optional<T>.
RxJava扩展
val values = Observable.just(Some("a"), None, Some("b"))
// Filter Some values.
values
.filterSome()
.test()
.assertValues("a", "b")
// Filter None values.
values
.filterNone()
.test()
.assertValues(Unit) // filterNone() maps None to Unit.
Reactor扩展
val values = Flux.just(Some("a"), None, Some("b"))
// Filter Some values.
values.filterSome()
// Filter None values.
values.filterNone()