scala中Either的一种使用场景

用scala有一年多了,对于scala中的Option和Try使用的较为频繁,对其应用场景相对熟悉一些。而对于Either,仔细回想一下却发现几乎(完全)没有使用过,其实并不是没有遇到过Either的使用场景,只是遇到的时候不知道能够使用Either来解决此问题。
昨天在网上偶然看到一篇介绍Either的文章,发现有一种场景可以使用Either来解决,具体是这样的:

  web系统中,Controller层调用service层方法,根据邮箱查询注册的用户User,如果未取到User,则需要知道是什么原因导致的。

定义一个方法,根据登录邮箱查询User对象,方法签名如: def getUserByEmail(email:String):User

注意方法的返回值类型,这里返回的是User对象。在运行时会发生如下三种情况:

  1、正常返回null

  2、正常返回User

  3、发生异常抛出Exception。

对于情况1,调用处如果想知道是为什么返回了null,是因为email的格式错误?还是因为该email没有注册的用户? 该种方法签名是没办法把失败原因返回给调用处的 。
那么我们考虑能否把返回结果类型User修改为Try[User],即:def getUserByEmail(email:String):Try[User]
  对于刚才的情况1,如果是因为email格式不对,我们在方法体内可以封装一个Failure(RuntimeException("邮箱格式错误"))返回给调用处。而如果是该邮箱未注册,未查询到该用户,如果再封装一个Exception就不合适了。因为查不到用户属于正常的逻辑,不属于异常范畴,这种方式是不可取的。
那么我们再考虑把返回值类型Try[User]修改为Option[User],即:def getUserByEmail(email:String):Option[User]
  这样,只是把把返回结果null修改为None,并未达到我们想要的目的
这时,我们就可以考虑把返回值类型修改为Either[String,User],即:def getUserByEmail(email:String):Either[String,User]

  如果查询到User,那么返回一个Right(user)即可,如果邮箱格式错误,则返回一个Left("邮箱格式错误"),如果该邮箱未进行注册,则返回Left("该邮箱未进行注册");如果运行中发生Exception,可以直接抛出,也可以封装为Left("发生XXX异常")返回给调用处。
除了通过Either来返回失败信息,我们也可以使用Tuple2[String,User]类型来实现想要的结果,在失败的时候返回Tuple2("失败原因描述",null),只是相对于Either来说,不是那么便捷。

使用方式可见如下伪代码:

 1  @Test
 2   def testEither(): Unit = {
 3     getUserByEmail("[email protected]") match {
 4       case Right(user) => ???
 5       case Left(msg) => println("查询用户失败,原因:" + msg)
 6     }
 7   }
 8
 9   def getUserByEmail(email: String): Either[String, User] = {
10     if (email无效) {
11       return Left("邮箱格式错误")
12     } else {
13       if (未查询到注册邮箱) {
14         return Left("该用户不存在")
15       } else {
16         return Right(user)
17       }
18     }
19   }

=========================================

原文链接:scala中Either的一种使用场景

=========================================

-------end

原文地址:https://www.cnblogs.com/PerkinsZhu/p/9450593.html

时间: 2024-11-08 22:34:35

scala中Either的一种使用场景的相关文章

Scala中的参数类型和延迟类型定义

在Scala中,有两种方式可以用来支撑高阶对象. 1. 类型参数: trait DataOps[A] { def show(a: A) = println(a) } val numbericOps = new DataOps[Int]{} 特质上有一个泛型A,当实例化类型的时候可以填入 2. 延迟定义到子类 trait DataOps { type A def show(a: A) = println(a) } val numbericOps = new DataOps { override t

Scala中使用implict 扩展现有类的方法

Scala中implict的一种用法就是扩展现有类的方法,有点类似于.Net中的扩展方法(MS对扩展方法的介绍:扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.) Scala中有两种方式做到方法的扩展,以扩展String为列: 第一种(code:10-12,29):创建一个以implict修饰的新类并以String类型入参.在新的类型(代码中是mystring)中添加要扩展的方法(read2) 第二种(code:3-5,9,28): 创建一个以i

scala中“=>”的4种使用场景

一直以来都对scala中"=>"的使用比较迷茫,也不知道他表示什么意思.今天就它的使用场景列举如下,希望可以共同探讨. 表示函数的返回类型(Function Type) scala> def double(x: Int): Int = x*2 double: (x: Int)Int //定义一个函数变量: scala> var x : (Int) => Int = double x: Int => Int = <function1> //调用

Numpy中Meshgrid函数介绍及2种应用场景

近期在好几个地方都看到meshgrid的使用,虽然之前也注意到meshgrid的用法.但总觉得印象不深刻,不是太了解meshgrid的应用场景.所以,本文将进一步介绍Numpy中meshgrid的用法. Meshgrid函数的基本用法 在Numpy的官方文章里,meshgrid函数的英文描述也显得文绉绉的,理解起来有些难度.可以这么理解,meshgrid函数用两个坐标轴上的点在平面上画网格.用法: [X,Y]=meshgrid(x,y) [X,Y]=meshgrid(x)与[X,Y]=meshg

Scala中apply的用法

Scala中的 apply 方法有着不同的含义, 对于函数来说该方法意味着调用function本身, 以下说明摘自Programming in Scala, 3rd Edition Every function value is an instance of some class that extends one of several FunctionN traits in package scala, such as Function0 for functions with no parame

Scala 深入浅出实战经典 第51讲:Scala中链式调用风格的实现代码实战及其在Spark中应用

王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2土豆:http://www.tudou.com/programs/view/5uuKOP38d6s/优酷:http://v.youku.com/v_show/id_

第81讲:Scala中List的构造和类型约束逆变、协变、下界详解

今天来学习一下scala中List的构造和类型约束等内容. 让我们来看一下代码 package scala.learn /** * @author zhang */abstract class Big_Data class Hadoop extends Big_Dataclass Spark extends Big_Data object List_Constructor {  def main(args:Array[String]){    val hadoop = new Hadoop ::

scala akka 修炼之路6(scala函数式柯里化风格应用场景分析)

胜败兵家事不期,包羞忍耻是男儿--斗牛士fighting,fighting,fighting... 小象学习和使用scala也一段时间了,最初小象学习scala主要为了学习spark生态,但是深入学习scala的一些特性后,深深被scala函数式和面向对象的风格所折服,不得不赞美设计这门语言的设计者.小象大学阶段在使用MATLAB做数据分析和自动化设计时,就非常喜欢使用MATLAB的命令行和面向矩阵运算的风格编写分析代码:喜欢使用java编写层次化和清晰的模块接口,而这些Scala语言设计中都有

Scala中的特质详解

Scala中的特质与Java中的接口是比较类似的,但是Scala中的特质可以同时拥有抽象方法和具体方法,而类可以实现多个特质.下面我们详细讲解Scala中的特质这个强大的功能. 1. 把特质当作接口使用 我们定义一个trait,如下所示: 1 trait Logger { 2 def log(msg: String) 3 } 需要注意的是trait中未被实现的方法默认是抽象方法,因此不需要在方法前加abstract. 子类ConsoleLogger对Logger的实现,如下所示: 1 class