可以/应该隐性转换,从T选择[T]可以加入/创建在卡拉?
-
20-09-2019 - |
题
这是一个机会,使事情变得有点更加有效(对于匙prorammer):我觉得它变得有点烦人具有包裹的东西在 Some
, 如 Some(5)
.什么事情是这样的:
implicit def T2OptionT( x : T) : Option[T] = if ( x == null ) None else Some(x)
解决方案
您会失去某种类型的安全性,并可能导致混乱。 例如:
val iThinkThisIsAList = 2
for (i <- iThinkThisIsAList) yield { i + 1 }
我(无论何种原因)认为我有一个列表,它没有编译器,当我遍历它,因为它是自动转换为一个选项[INT]。抓到
我要补充一点,我觉得这是一个伟大的隐含已经明确地进口的,只是可能不是全局默认值。
其他提示
请注意,您可以使用这将避免混淆显性隐性模式并保持代码简洁的同时。
我通过明确的隐含的意思是不是有从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)
...我会为它找到一个更好的名字比Optionable
,但现在你可以这样写代码:
val x: String = "foo"
x.toOption // Some("foo")
val y: String = null
x.toOption // None
我相信这种方式是完全透明的,在写代码的理解艾滋病 - 消除一个很好的方式为空所有检查
请注意的T <: AnyRef
- 你应该只用于类型允许null
值,其定义是引用类型为此隐式转换
一般指导方针的隐性转换如下:
- 当你需要添加的成员类型(a la"开放式课程";又名"我的皮条客库"模式),转换为一个 新的 类型的延伸
AnyRef
而这仅仅定义了该成员的需要。 - 当你需要的"正确"继承层次结构。因此,你有某种类型
A
哪 应该有 子类B
, 但是没有因为某些原因。在这种情况下,可以定义的隐性转换A
要B
.
这些都是的 只 情况是适当的定义隐含的转换。其他任何转换成类型的安全性和正确性问题,在匆忙。
这真的没有任何意义 T
延长 Option[T]
, 显然的目的转换并不是简单的加的成员。因此,这种转换将是不可取的。
这似乎是这可能会造成混乱给其他开发者,因为他们读你的代码。
一般而言,现在看来,implicit
致力于帮助投从一个对象到另一个,切出混乱铸造代码,可能会搞乱代码,但是,如果我有一些变量,它在某种程度上成为一个Some
那么这似乎是麻烦
您可能希望将显示它的一些代码中使用了,看看它是如何混乱是。
您也可以尝试重载方法:
def having(key:String) = having(key, None)
def having(key:String, default:String) = having(key, Some(default))
def having(key: String, default: Option[String]=Option.empty) : Create = {
keys += ( (key, default) )
this
}
这对我来说很好,但它可能不适合一个原始科技工作(其不能为空)。我想非专业一般总是得到盒装元,所以可能它的罚款。