T から Option[T] への暗黙的な変換を Scala で追加/作成できますか?
-
20-09-2019 - |
質問
これは (プログラマーにとって) 作業をもう少し効率化する機会ですか:何かをまとめるのは少し面倒だと思う 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
値を許可するタイプのため、この暗黙の型変換を行う必要があります。
暗黙的な変換の一般的なガイドラインは次のとおりです。
- 型にメンバーを追加する必要がある場合 (「オープン クラス」。別名「pimp my library」パターン)、に変換します。 新しい 伸びるタイプ
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
}
、それが(NULLにすることはできません)プリミティブTのために動作しない場合があり除き、私にはよさそうです。私は、おそらくそれは大丈夫です、非専門のジェネリック常に箱入りますプリミティブを推測します。