请解释 Option 的 orNull 方法的使用
Scala 的 Option 类有一个 orNull
方法,其签名如下所示。
orNull [A1 >: A](implicit ev : <:<[Null, A1]) : A1
我对隐含的东西感到困惑。有人可以解释一下它的使用方法吗,最好是举个例子?
Scala's Option class has an orNull
method, whose signature is shown below.
orNull [A1 >: A](implicit ev : <:<[Null, A1]) : A1
I'm bewildered by the implicit thing. Would somebody please explain how it can be used, ideally with an example?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
解释一下隐含的事情:orNull 是一种从 Some|None 习惯用法回到 Java 的 value|null 习惯用法的方法(这当然是不好的)。现在只有 AnyRef 值(类的实例)可以接受空值。
所以我们想要的是
def orNull[A >: Null] = ....
。但 A 已经设置,我们不想在特征的定义中限制它。因此,orNull 需要 A 是可为 null 类型的证据。该证据采用隐式变量的形式(因此名称为“ev”)<:<[Null, A1]
可以写为Null <:< A1
这样看,就类似于'Null <: A1'。 <:<在 Predef 中定义,并提供名为conforms
的隐式值的方法。我认为这里并不严格要求使用 A1 ,这是因为 orNull 使用 getOrElse (其中给出的默认值可以是 A 的超类型)
To explain the implicit thing: orNull is a way of getting back from the Some|None idiom to Java's value|null idiom (which is, of course, bad). Now only AnyRef values (instances of classes) can accept a null value.
So what we would have liked is
def orNull[A >: Null] = ....
. But A is already set and we don't want to restrict it in the definition of the trait. Therefore, orNull expects an evidence that A is a nullable type. This evidence is in the form of an implicit variable (hence the name 'ev')<:<[Null, A1]
can be written asNull <:< A1
seeing it like this, it is similar to 'Null <: A1'. <:< is defined in Predef as well as the method that provides the implicit value namedconforms
.I think the use of A1 is not strictly required here and is because orNull uses getOrElse (where the default given can be a super type of A)
orNull
的目的首先是确保Option
与 Java 的兼容性。尽管在 Scala 中不鼓励使用null
,但某些接口可能期望获得可为 null 的引用。orNull
有一个简单的实现:根据此,不仅对于装箱的 null (
Some(null)
) 会返回null
,对于None
(例如,如果调用None.get
,将抛出异常)。隐式参数检查装箱值是否可为空。
好的用法示例可以在 对
orNull
的注释:orNull
purpose is first of all in ensuring compatibility ofOption
with Java. Though usage ofnull
is discouraged in Scala, some interfaces may expect to get nullable references.orNull
has a straightforward implementation:According to this,
null
will be returned not only for boxed nulls (Some(null)
), but also forNone
(e.g., if you callNone.get
, exception will be thrown).Implicit parameter checks, if the boxed value is nullable.
Good usage example can be found right in the comments to
orNull
:请记住,在 Scala 中,基本类型和引用类型是统一的 - 但只有引用类型可以为 null。隐式仅允许编译器确认 A1 是引用类型。
Remember that in Scala primitive types and reference types are unified - but only reference types are nullable. The implicit simply allows the compiler to confirm that A1 is a reference type.
为了理解它为什么有用,IttayD 提供了很好的解释:
总之,当您希望在泛型类(例如
Option
)上使用具有更具体约束(例如orNull
)的方法(例如orNull
)时,类型约束非常有用。 >Null <: A <: Any)而不是类本身(例如A <: Any
)。这是另一个未内置于语言中的“功能”,但由于隐式参数和类型参数的方差注释而免费提供。要理解这一点,请查看
<:<
的定义:编译器会
查找
<:<[Null, Int]
类型的隐式值,并且会发现方法def cons[A]: A <:<一个。因此必须有一个
A
,其中<:<[A, A]
符合<:<[Null, Int]
代码>.没有A
可以满足此要求,因此编译器会抱怨缺少隐式值。不过,对于
我们来说,还是幸运的。现在,编译器尝试查找
<:<[A, A]
符合<:<[Null, String] 的
。这适用于A
A = String
,因为Null
是String
的子类型以及该类的From
类型参数<:<
被定义为逆变)。如前所述,考虑类型约束的最直观方法是像类型绑定一样读取它(即将其读取为 Null <: Int)。
Null
不符合Int
并且 <:<[Null, Int] 没有隐式值。另一方面,Null
确实符合String
,编译器会找到隐式参数。顺便说一下,这是另一个相关答案。
To understand why it is useful, IttayD provided a nice explanation:
In summary, type constraints are useful when you want have methods (eg
orNull
) on a generic class (egOption
) with more specific constraints (egNull <: A <: Any
) than on the class itself (egA <: Any
).This is another "feature" that is not built into the language but comes for free thanks to implicit parameters and variance annotations of type parameters. To understand this, look at the definition of
<:<
:For
the compiler looks for an implicit value of type
<:<[Null, Int]
and will find the methoddef conforms[A]: A <:< A
. So there has to be anA
for which<:<[A, A]
conforms to<:<[Null, Int]
. There is noA
for which this holds and as a result the compiler will complain about the missing implicit value.However, for
we are lucky. Now, the compiler tries to find an
A
for which<:<[A, A]
conforms to<:<[Null, String]
. This works forA = String
, becauseNull
is a subtype ofString
and theFrom
type parameter of the class<:<
is defined as contravariant).As mentioned, the most intuitive way to think about type constraints is reading it like a type bound (i.e. reading it as Null <: Int).
Null
does not conform toInt
and there is no implicit value for <:<[Null, Int]. On the other hand,Null
does conform toString
and the compiler will find the implicit parameter.By the way, here is another related answer.
回复:“如何”使用它 - 我们发现它有用的一个地方是在处理 java api 映射时,其中
null
很常见,例如,在 jdbc 准备好的语句到可为 null 的 sql 列上。可以映射Option
al内部模型字段:而不是更详细的:
Re : 'how' is this used - one place we are finding this useful is when dealing with java api mappings where
null
is commonplace, e.g. on jdbc prepared statements to nullable sql columns. TheOption
al internal model fields can be mapped:Instead of the more verbose: