Scala中的Option
空值处理背景
在Java中,空值被定义为null
。这是一个特殊的关键字,用来表示某个引用为空。正是因为这只是一个关键字,而不是一个对象,因此用它调用任何方法都是非法的。但是仔细思考,这一点实际上存在不合理的地方,我们明明希望返回的是一个对象,可是返回的却是一个关键字。
于是在Scala中,使用Option
对象来对这一现象进行处理。Option类表示的是那种可能存在,也可能不存在的值,对应到Java中,就是说这个值可能为null。但是由于使用Option进行了一层包装,无论值是否存在,返回的都是一个对象,可以进行方法调用。一个很好的编程习惯是当方法的返回值有可能为null的时候,都使用Option对象来代替。
Option
为了使得一切皆对象的目标更加一致,Scala鼓励在变量和函数返回值可能不会引用任何值的时候使用Option类型。在没有值的时候,使用None;在有值的时候,则使用Some来包装这个值。
Option[T]
是一个带泛型的类,我们可以将其看作是一个包装了某个值的容器。Some
和None
都是Option的子类。Some是一个class,表示有值;None是一个object,表示没有值。Some和None都可以调用isEmpty
以及get
方法:
- 在调用isEmpty方法的时候,Some返回false,而None返回true
- 在调用get方法的时候,Some返回对应被包装的value,而None会抛出
NoSuchElementException
错误
因此我们在接收一个Option对象之后,应该通过调用isEmpty
来判断是否为空,然后选择如何处理。通过下面的例子,我们可以更好地理解Option
的使用。
1 |
|
这里我们定义了一个将字符串转化为Int的函数,这个函数的返回值是有可能不存在的,因此我们将返回值定义为Option的形式。如果解析成功,能够返回,那么就使用Some进行包装,否则就返回None。
要使用这个函数,则需要在使用结果之前进行判断:
1 |
|
而借助于Scala中强大的模式匹配,我们也可以通过下面的方式来处理:
1 |
|
简单总结Option的使用,就是将我们需要返回的实际值使用Option进行包装,其中泛型指定为对应的类型。当正常返回值的时候,使用Some进行包装,异常的时候则直接返回None。Option类型的值通常作为Scala集合类型操作的返回类型。
使用Option的好处在于返回了一个统一的对象,无论真实值是否存在,都能够进行方法的调用。在Java中,我们可以利用!= null
来进行空值的处理,但是如果一个不小心没有处理到,就很容易出现NullPointException异常,并且出现异常之后,问题排查是一个比较难的问题。另一方面,一个Java方法是否会返回空值无法通过返回值看出来,只能通过看相关文档。而Scala的Option类型可以避免这种情况,使用Option类型就表示这个地方可能返回None。
Option类型本身还有一些相关的方法,列举如下:
方法 | 描述 |
---|---|
def get: A | 获取对应的值 |
def getOrElse(B): A | 获取对应的值,如果是None则返回默认值 |
def isEmpty: Boolean | 检查是否为None,是返回true,否则返回false |
def isDefined: Boolean | 与上面相反,检查是否为Some。是返回true,否则返回false |