我是scala的新手。有人可以向我解释下面这段代码吗?
val l: Either[String, Int] = Left("flower")
val r: Either[String, Int] = Right(12)
l.left.map(_.size): Either[Int, Int] // Left(6)
r.left.map(_.size): Either[Int, Int] // Right(12)
关于第3行和第4行,我有几个问题:
谢谢!
答案 0 :(得分:5)
第一行定义类型为l
的变量Either[String, Int]
。 Either
(抽象)类用于表示何时某些内容可以包含两个可能值中的一个。 Left
和Right
类子类Either
,因此是有效的赋值。惯例是使用Left
来表示某种失败(例如,String
描述出错的地方),Right
来表示某种成功的计算/值。有了这些信息,第二行也是相当自我解释的。
第3行和第4行使用l
和r
变量上的投影并执行map
。 left
和right
方法返回投影..如果您在left
变量上投放Left
,则可以map
覆盖内部值。如果您在right
变量上投放Left
,即使在Right
之后,您的map
也未被更改。如果您在right
上执行Left
,则相同
所以第3行,因为l
是Left
而你left
投影它,你将map
应用于Left("flower")
值给你{ {1}}因为“花”的长度为6。
在第4行,Left(6)
为r
,因此无效。
对于你的问题:
Right
是传递给_.size
方法的函数。map
方法“解包”map
内的值(它对第4行Left
,因为它是左投影)并在其上调用Right
。
.size
会在r.left
值上返回左侧投影。对此进行映射无效,如代码第4行所示。
相同的旧Right(12)
值。
由于它是Right(12)
且类型为Right(12)
,因此它是Right[_, Int]
的子类,因此它是有效的。它只是显示我相信的类型。
如果你转到REPL并输入类似Either[Int, Int]
的内容,你会得到一个类型val foo = Right(1234)
- 这个“有效”,因为Right[Nothing, Int]
类型是所有类型的子类。
在相关的说明中,一旦你开始对这个和/或Scala感到满意,我建议结帐Scalaz(一个Scala库,提供类型类,monad和所有好东西等函数式编程)和{{ 1}}类与Nothing
非常相似。