我注意到Option.flatten
为defined如下:
def flatten[B](implicit ev: A <:< Option[B]): Option[B] = if (isEmpty) None else ev(this.get)
这里ev
是什么? A <:< Option[B]
是什么意思?它用于什么?
答案 0 :(得分:14)
这是限制某些方法针对特定类型执行的常见做法。实际上,<:<
是scala.Predef
中定义的类型,如下所示:
@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
...
implicit def conforms[A]: A <:< A = ...
因此,只有当A是B的子类型时才能解析类型<:<[A, B]
的隐式。
在这种情况下,只有当Option
包含在另一个Option
中时,才能解析它。在任何其他情况下,将发生编译错误:
scala> Option(42).flatten
<console>:8: error: Cannot prove that Int <:< Option[B].
Option(42).flatten
^
答案 1 :(得分:3)
作为ScalaDoc says - An instance of A <:< B witnesses that A is a subtype of B
。
因此,在这种情况下,Option
只有在内部包含另一个Option
时才能展平。
Option[Option[String]]
展平为Option[String]
答案 2 :(得分:2)
<:<
是'广义类型约束'或'类型证据'。它们由编译器提供,可用于进一步约束泛型类型参数。在这种情况下,约束是类型A
必须是Option[B]
的子类型,即该选项是某种类型T
的嵌套选项[Option [T]]。