ñull
is sometimes considered the billion dollar mistake. One could argue about this forever, but certainly, null
has lead to a lot of awful code.
Most functional programming languages offer a concept called Option or 中号aybe to deal with the presence or absence of a value, thus avoiding null
. Wikipedia defines the Option type as follows:
在编程语言(功能编程语言更是如此)和类型理论中,选项类型或可能的类型是表示封装可选值的多态类型。 例如,它用作函数的返回类型,在应用它们时可能会或可能不会返回有意义的值。
这篇简短的帖子赞扬了Vavr版本的选项。 我们展示了如何使用它,并展示了它相对于JDK8的优势选项al。
Vavr - Elevator pitch
Vavr, previously known as Javaslang, is a lightweight library that brings Scala-like features to Java 8 projects. It focuses on providing a great developer experience both through consistent APIs and extensive documentation.
Vavr提供了许多抽象,例如功能数据结构,值类型懒和要么和structural decomposition (a。k。a。 pattern matching on objects)。 Here we'll only highlight the Vavr 选项。
如果您曾经渴望获得非常好的不可变和持久性的收藏,有效的价值类型,但由于正在从事棕地项目而无法迁移到Scala和朋友那里,那么Vavr可能就是您的解决方案。
Optional FTW
Java 8引入可选的处理值的缺失或存在。 不带可选的,当您面对这样的方法时
public User findUser(String id) {
...
}
您需要依靠Javadoc或类似的注释@NotNull解密该方法是否返回一个空值。
使用可选的事情可以说得很明确:
public Optional<User> findUser(String id) {
...
}
这从字面上说“有时没有用户返回”。空值-safe。Say "adios" to NullPointerExceptions。
However...
与Java 8的所有功能接口一样,选装件API相当简陋,只有十几种方法,具有“重点”,例如
Optional.ofNullable(user)
如果您习惯了Scala的表现力选项,那么您会发现选项al相当令人失望。
Furthermore, Optional
is not serializable and should neither be used as an argument type nor stored as a field - at least according to the design goals of the JDK experts (http://mail.openjdk.java.net/pipermail/jdk8-dev/2013-September/003274.html).
Vavr Option
to the rescue
Vavr选项采用不同的方法。 请参见下图,该图说明了类型层次结构。
选项遵循其他功能性编程语言的设计,通过不同的类表示缺席和在场,没有和一些分别。 从而避免空值废话。
Option.of(user)
结果将是Some<User>或一个None<User>。
内部缺席表示为空值,所以如果您想包装一个空值,您需要使用
Option.some(null)
尽管我不推荐这种方法。 只需尝试以下代码段,您就会明白我的意思
Option.<String>some(null)
.map(String::toUpperCase);
选项与Vavr的紧密集成值和可迭代的类型。 这允许非常一致的API。 你基本上可以治疗选项就像一个零或一个元素的集合。
这听起来像一件小事,但考虑一下此JDK8可选的例。 我们有一个用户列表。
List<User> users = new ArrayList<>(...);
现在Optional<User>我们要添加到列表中。
Optional<User> optionalUser = Optional.ofNullable(user);
optionalUser.map(users::add);
JDK8强制执行的巴洛克式语法中失去了意图采集和可选的API。
瓦夫选项允许使用更简洁的语法(请注意,我们正在使用io.vavr.collection.List<T>不java.util.List<T>)。
List<User> users = List.of(...);
Option<User> optionUser = Option.of(user);
List<User> moreUsers = users.appendAll(optionUser);
Vavr对待Some<T>作为具有一个元素的集合,并且None<T>作为一个空集合,从而导致代码更简洁。 另外,请注意,将创建一个新列表,因为Vavr集合是不可变的且持久的-这是另一天的主题。
选项为我们提供了更多语法糖:
Option<String> driverName = Option.when(age > 18, this::loadDrivingPermit)
// Option<DrivingPermit>
.peek(System.out::println)
// Print it to the console
.map(DrivingPermit::getDriverName)
// Fetch the driver's name
.peek(System.out::println);
// Print it to the console
当然,正如我所说,是 basically sugar, but anything that reduced boilerplate code 是 highly appreciated.
选项已完全集成到Vavr的整体API和体系结构中。 您可以轻松地将其与Vavr的尝试monad,这有助于从功能上处理异常。 请看下面的例子。
Option<Configuration> config = Try.of(Configuration::load)
.toOption();
我们尝试加载一个组态并将结果转换为选项。 如果抛出异常,则 结果是没有否则是一些。
最后,您可以使用Vavr的模式匹配来分解选项
Match(option).of(
Case($Some($()), String::toUpperCase),
Case($None(), () -> ""));
如果您曾经使用功能性编程语言进行编码,那么您应该对此感到熟悉。 我们基本上比赛针对两种模式的选择$ Some($())和$ None()。 根据匹配的模式,我们将字符串转换为大写或返回空字符串。
Using Vavr Jackson you can even use Option
and all other Vavr datatypes over the wire. For Spring Boot projects you only need to declare the module such as:
@Bean
public Module vavrModule() {
return new VavrModule();
}
Summary
我希望这篇简短的帖子能够说明Vavr及其功能的实用性选项抽象。
Vavr作为一个库,为Java中的对象功能编程提供了许多惊人的扩展,甚至对于棕地项目也是如此。 您可以在有意义的地方利用它的实用程序,而不必迁移到Scala或类似平台上,以至少从功能编程中获得一些好处。
当然,这都是语法糖。 但是,正如任何好的库一样,Vavr可以修复问题,而核心JDK不会轻易处理而不破坏大量代码。
将来的文章将介绍它的其他惊人功能,例如模式匹配,基于属性的测试,集合和其他功能增强。