これは物事をもう少し効率的にする機会ですか (プロランマーにとって): でラップする必要があるのは少し面倒だと思いSome
ますSome(5)
。このようなものはどうですか:
implicit def T2OptionT( x : T) : Option[T] = if ( x == null ) None else Some(x)
これは物事をもう少し効率的にする機会ですか (プロランマーにとって): でラップする必要があるのは少し面倒だと思い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 }
私は (何らかの理由で) リストを持っていると思っていましたが、Option[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
この方法は完全に透過的であり、記述されたコードの理解に役立つと信じています-良い方法でnullのすべてのチェックを排除します.
注意T <: AnyRef
- この暗黙的な変換は、null
値を許可する型 (定義上は参照型) に対してのみ行う必要があります。
暗黙的な変換の一般的なガイドラインは次のとおりです。
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
}
プリミティブ T (null にすることはできません) では機能しない可能性があることを除けば、それは私には良さそうです。特殊化されていないジェネリックは常にボックス化されたプリミティブを取得すると思うので、おそらく問題ありません。