這是一個讓事情變得更有效率的機會(對於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