Ale*_*ack 35 scala scala-option
这是一个让事情变得更有效率的机会(对于程序员而言):我觉得不得不把事情包裹起来Some
,例如Some(5)
.这样的事情怎么样:
implicit def T2OptionT( x : T) : Option[T] = if ( x == null ) None else Some(x)
Run Code Online (Sandbox Code Playgroud)
Mit*_*ins 31
你会失去某种类型的安全性并可能引起混淆.例如:
val iThinkThisIsAList = 2
for (i <- iThinkThisIsAList) yield { i + 1 }
Run Code Online (Sandbox Code Playgroud)
我(无论出于何种原因)认为我有一个列表,当我迭代它时它没有被编译器捕获,因为它被自动转换为Option [Int].
我应该补充一点,我认为明确导入这是一个很好的隐含,可能不是全局默认.
Fla*_*gan 27
请注意,您可以使用显式隐式模式,以避免混淆并同时保持代码简洁.
我所说的显式隐式是指而不是直接转换T
为Option[T]
你可以转换为包装器对象,它提供了从中进行转换的T
方法Option[T]
.
class Optionable[T <: AnyRef](value: T) {
def toOption: Option[T] = if ( value == null ) None else Some(value)
}
implicit def anyRefToOptionable[T <: AnyRef](value: T) = new Optionable(value)
Run Code Online (Sandbox Code Playgroud)
...我可能会找到比它更好的名字Optionable
,但现在你可以编写如下代码:
val x: String = "foo"
x.toOption // Some("foo")
val y: String = null
x.toOption // None
Run Code Online (Sandbox Code Playgroud)
我相信这种方式是完全透明的,有助于理解编写的代码 - 以一种很好的方式消除对null的所有检查.
请注意T <: AnyRef
- 您应该仅对允许null
值的类型执行此隐式转换,根据定义,这些值是引用类型.
Dan*_*wak 12
隐式转换的一般准则如下:
AnyRef
,它只定义你需要的成员.A
哪些应该子类B
,但并没有因为某些原因.在这种情况下,你可以定义从隐式转换A
到B
.这些是唯一适合定义隐式转换的情况.任何其他转换都会匆忙进入类型安全和正确性问题.
T
扩展真的没有任何意义Option[T]
,显然转换的目的不仅仅是增加成员.因此,这种转换是不可取的.