Scala中的Option/Some/None和Try/Success/Failure

Option/Some/None和Try/Success/Failure出现的意义

在Scala中有一个非常重要的思想——避免null。很多Scala程序员都是Java程序员,Java中的null和空指针异常几乎可以说是无处不在。而在Scala中有一条非常重要的思想就是从意识中抹去有null关键字这回事。这也是Option/Some/None和Try/Success/Failure存在的意义。

微信公众号:大数据报文

Option/Some/None

可以简单的认为Some和None是Option的两种不同表现形式,如果Option中有内容,就是Some,如果没有内容就是None.而None一般是在Some取不到值的时候(比如空指针的时候),或者说程序有异常的时候才会取到None,但是None本身并不会携带任何异常信息。 

def toInt(strNum: String):Option[Int] = {
    try {
        Some(Integer.parseInt(strNum.trim))
    }catch {
        case e: Exception => {
            println(e.getMessge)//在try后打印异常信息,然后将None作为返回值返回
            None
    }
}

上面定义了一个方法,基本思想就是将本该返回的结果使用Some包裹一下,使用Some()或者None代替空指针的情况。但是None本质还是空指针啊,比如返回结果result调用get()方法的时候依然会有异常产生。

这里就牵扯到另外一个问题即Option对象如何取值的问题。

Option对象取值问题

上面提到了使用get方法,None.get仍然是会报空指针的,因为这是一种Java思想,在Scala中提供了三种不同的方式去获取Option对象的值。

1.getOrElse方式

这是一种简单而行之有效的方式,如果Option中有值就获取,没有就使用提供的默认值。

toInt("aa").getOrElse(0)

2.使用模式匹配的方式

toInt("234") match {
    case Some(n) => println(s"$n")
    case None => println("not a number")
}

3.使用foreach方法

本质上Some()中包含0个或者多个值,使用foreach方法是肯定行得通的。

toInt("12").foreach(println)

Try/Success/Failure

Option/Some/None类似,Success和Failure是Try的两种不同表现形式,如果成功表现为Success,如果失败表现为Failure。但是与Option/Some/None不同的是,在Failure中会携带异常信息。

关于取值方面,与上面的Option一样支持三种方式。

//如果y传入的非0,会返回Success(结果)
//如果y传入的为0,会返回Failure(异常信息)
def divideXByY(x:Int,y:Int):Try[Int] =  {
    Try(x/y)
}
//取值跟Option一致
divideXByY(1,0).getOrElse(0) //如果抛出异常就是0,否则就是计算结果

//下面使用模式匹配的方式可以打印异常信息,这样处理会比上面优雅很多
divideXByY(1,2) match {
    case Success(i) => println(s"Success, value is $i")
    case Failure(e) => println(s"Failure, message is $e")
}

//另外一个例子。在进行数字转换的时候如果转换失败,也不会导致代码中断
def anotherDemo(x: String, y: String): Unit = {
    val z = for {
        a <- Try(x.toInt)
        b <- Try(y.toInt)
    } yield a * b
    val answer = z.getOrElse(0) * 2
    println(answer)
}

同时Try/Success/Failure是可以转化为Option/Some/None的。

Success("hello").toOption

 

你可能感兴趣的:(Scala)