发布网友 发布时间:2022-04-21 17:59
共1个回答
热心网友 时间:2023-06-23 03:04
Option是一个很有意思的类,首先,这个类并不一个真正的集合类,因为它并没有有继承Traversable或Iterable。但是,它确实具有Iterable的所有操作,这意味着你完全可以把Option当成一个集合去使用,其中原因你应该可以猜的到,这显然是隐式转换在起作用。具体来说是Option的伴生对象中定义了一个隐式转化函数option2Iterable, 你还记得隐式解析的作用域吗?伴生对象也是编译器针对类型进行隐式转换解析时查找的作用域,也就是说:当你试图把Option当成一个Iterable使用时,编译器是在Option的伴生对象的option2Iterable方法上找到了这个隐式转化声明:
implicit def option2Iterable[A](xo: Option[A]): Iterable[A]12
从而确认了从Option向Iterable的隐式转化是定义好的。(至于另外的4个隐式转换:by any2stringadd, by any2stringfmt, by any2ArrowAssoc, by any2Ensuring是发生在PreDef中的,这4个是面向全局的任何类型的隐式转换。
其次,我们来看一下这个类两个子类:
First, it is far more obvious to readers of code that a variable whose type
is Option[String] is an optional String than a variable of type String,
which may sometimes be null. But most importantly, that programming
error described earlier of using a variable that may be null without first
checking it for null becomes in Scala a type error. If a variable is of type
Option[String] and you try to use it as a String, your Scala program will
not compile.
Option具有更直白的语义:它代表的值可能是一个具体的值,但也可能是空!
在Java里判空是一个运行时的动作,因此经常会出现忘记判空导致的空指针异常。但是在scala里,由于Option的引入,在你试图使用Option里的值时,你必选做相应的类型转换,否则就会出现编译错误,这是引入Option另一个重要目的,在编译期进行判空处理!
比如:当你声明一个Option[String]变量时,从语义上你就已经告知了编译器,包括读者,这个变量可能是一个String也可能是空,但是在试图实际读取这个值时,你必须先进行类型转换和判空处理,否则编译就无法通过,这是使用Option的主要同目的。
Option在Scala里被广泛使用,主要有如下场景:
Using Option in method and constructor parameters
Using Option to initialize class fields (instead of using null)
Converting null results from other code (such as Java code) into an Option
Returning an Option from a method
Getting the value from an Option
Using Option with collections
Using Option with frameworks
Using Try/Success/Failure when you need the error message (Scala 2.10 and
newer)
Using Either/Left/Right when you need the error message (pre-Scala 2.10)
其次,我们来看一下这个类两个子类:
Returning an Option from a method
def toInt(s: String): Option[Int] = { try {Getting the value from an Option
这里有三个类子演示从一个Option里提取值:
Use getOrElse
scala> val x = toInt("1").getOrElse(0)getOrElse:顾名思义,对于一个Option,如有它确实有值就返回值,否则,也就是为空的话,给一个约定的值。
Use foreach
由于是Option可以被隐式转换为Iterable,这意味着你可以把它当成一个普通的集合那样去使用,使用foreach去迭代一个Option就是非常典型的例子。
toInt("1").foreach{ i =>Use a match expression
toInt("1") match { case Some(i) => println(i) case None => println("That didn't work.")