Dav*_*vid 18 api scala scala-java-interop
Scala的Option类有一个orNull方法,其签名如下所示.
orNull [A1 >: A](implicit ev : <:<[Null, A1]) : A1
Run Code Online (Sandbox Code Playgroud)
我被隐含的东西弄糊涂了.有人请说明如何使用它,理想情况下是一个例子吗?
Itt*_*ayD 31
scala> Some(1).orNull
<console>:10: error: could not find implicit value for parameter ev: <:<[Null,Int]
Some(1).orNull
^
scala> (None : Option[Int]).orNull
<console>:10: error: could not find implicit value for parameter ev: <:<[Null,Int]
(None : Option[Int]).orNull
scala> Some("hi").orNull
res21: java.lang.String = hi
scala> Some(null : String).orNull
res22: String = null
scala> (None : Option[String]).orNull
res23: String = null
Run Code Online (Sandbox Code Playgroud)
为了解释隐含的东西:orNull是获得来自一些回来的路|无成语Java的价值|空成语(这是当然的,坏).现在只有AnyRef值(类的实例)可以接受空值.
所以我们会喜欢的是def orNull[A >: Null] = .....但是A已经设置好了,我们不想在特征的定义中限制它.因此,orNull期望证明A是可以为空的类型.这个证据是一个隐含变量的形式(因此名称'ev')
<:<[Null, A1]可以写成这样Null <:< A1看,它类似于'Null <:A1'.<:<在Predef中定义,以及提供名为的隐式值的方法conforms.
我认为这里并不严格要求使用A1,因为orNull使用getOrElse(默认给定的可以是A的超类型)
scala> class Wrapper[A](option: Option[A]) {
| def orNull(implicit ev: Null <:< A): A = if(option.isEmpty) null else option.get
| }
defined class Wrapper
scala> new Wrapper(Some("hi")).orNull
res18: java.lang.String = hi
Run Code Online (Sandbox Code Playgroud)
orNull目的首先是确保Option与Java的兼容性.虽然null在Scala中不鼓励使用,但某些接口可能会获得可以为空的引用.
orNull 有一个简单的实现:
def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null
Run Code Online (Sandbox Code Playgroud)
根据这个,null不仅会返回boxed nulls(Some(null)),而且还会返回None(例如,如果你调用None.get,将抛出异常).
如果装箱值可以为空,则进行隐式参数检查.
良好的用法示例可以在评论中找到orNull:
val initialText: Option[String] = getInitialText
val textField = new JComponent(initialText.orNull,20)
Run Code Online (Sandbox Code Playgroud)