这是一个让事情变得更有效率的机会(对于prorammer):我发现它有些烦人,不得不将东西包装在Some
中,例如, Some(5)
。那么像这样的事情:可以在Scala中添加/创建从T到Option [T]的隐式转换吗?
implicit def T2OptionT(x : T) : Option[T] = if (x == null) None else Some(x)
这是一个让事情变得更有效率的机会(对于prorammer):我发现它有些烦人,不得不将东西包装在Some
中,例如, Some(5)
。那么像这样的事情:可以在Scala中添加/创建从T到Option [T]的隐式转换吗?
implicit def T2OptionT(x : T) : Option[T] = if (x == null) None else Some(x)
你会失去一些类型的安全性,并可能导致混淆。 例如:
val iThinkThisIsAList = 2
for (i <- iThinkThisIsAList) yield { i + 1 }
我(无论何种原因)认为我有一个列表,它没有编译器,当我遍历它,因为它是自动转换为一个选项被逮住[INT] 。
我应该补充一点,我认为这是一个很好的隐含显式导入,可能不是全局默认。
看起来,这可能会让其他开发人员感到困惑,因为他们读取您的代码。
一般来说,似乎implicit
致力于帮助投从一个对象到另一个,切出混乱铸造代码,可能会搞乱代码,但是,如果我有一些变量,它在某种程度上成为一个Some
那么这似乎是麻烦。
您可能想要放一些代码来显示它正在使用,看看它会有多混乱。
我得到你的意思。不过,选项的[T]的一点是,它可以容纳一个值或无,所以它看起来直观我认为如果一个方法需要一个Option [T]类型的变量,我应该能够将T传递给它。您能否想到一个您可能会产生混淆的例子,例如一个变量无意中变成了一些? – 2009-11-17 03:26:38
对我来说这看起来不错,但它可能不适用于原始T(不能为空)。我想一个非专门的通用总是获得盒装原语,所以可能没关系。
请注意,您可以使用explicit implicit模式,以避免混淆并保持代码简洁。
我的意思是明确的暗示是什么,而不是有从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
我相信这种方式是完全透明的,在认识艾滋病书面代码 - 以很好的方式消除null的所有检查。
请注意T <: AnyRef
- 对于允许使用null
值的类型,您应该只进行这种隐式转换,该值根据定义是引用类型。
嗨Flaviu,有趣的建议。我喜欢整体 - 尽管我认为这会让我的问题变得更糟,现在不是输入Some()我必须输入toOption ...但它确实具有使用null的优点。 – 2009-11-17 14:48:58
'Option(x)'(而不是'Some(x)')也适用于null。 (x:T){ def toOption:Option [T] = if(x!= null)Option(x)else None } – schmmd 2011-11-30 23:26:33
@ flaviu-cipcigan,做相同但更短 - 隐式类IntWithTimes [T] – Maxim 2014-11-30 12:46:33
的隐式转换的一般准则如下:
AnyRef
,它只定义你需要的成员。A
,其中应具有子类B
,但没有出于某种原因。在这种情况下,您可以定义从A
到B
的隐式转换。这些是只有适用于定义隐式转换的情况。任何其他转换都会匆忙地进入类型安全和正确性问题。
对T
来说延长Option[T]
确实没有任何意义,显然转换的目的不是简单地增加成员。因此,这种转换是不可取的。
您也可以尝试重载方法:
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
}
至少在IntelliJ IDEA中,我可以看到什么东西被自动转换(默认情况下它被加下划线)。但也许应该有一种方法来指定隐式转换应该只在将值传递给方法时发生,而不是在调用方法时发生。 – herman 2015-02-25 14:34:04