36

これは物事をもう少し効率的にする機会ですか (プロランマーにとって): でラップする必要があるのは少し面倒だと思いSomeますSome(5)。このようなものはどうですか:

implicit def T2OptionT( x : T) : Option[T] = if ( x == null ) None else Some(x)
4

6 に答える 6

31

型の安全性が失われ、混乱を招く可能性があります。例えば:

  val iThinkThisIsAList = 2 
  for (i <- iThinkThisIsAList) yield { i + 1 }

私は (何らかの理由で) リストを持っていると思っていましたが、Option[Int] に自動変換されていたので、反復処理を行ったときにコンパイラにキャッチされませんでした。

これは、明示的にインポートされたのは暗黙的であり、おそらくグローバルなデフォルトではないと思うことを付け加えておきます。

于 2009-11-17T03:30:13.543 に答える
27

混乱を回避し、同時にコードを簡潔に保つ明示的な暗黙のパターンを使用できることに注意してください。

T明示的な暗黙的とは、 からへの直接変換ではなく、 からへOption[T]の変換を行う手段を提供するラッパー オブジェクトへの変換を行うことができるということです。TOption[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値を許可する型 (定義上は参照型) に対してのみ行う必要があります。

于 2009-11-17T07:29:30.017 に答える
12

暗黙的な変換の一般的なガイドラインは次のとおりです。

  • タイプにメンバーを追加する必要がある場合(「オープンクラス」、別名「pimp mylibrary」パターン)、拡張し、必要なメンバーのみを定義する新しいタイプに変換します。AnyRef
  • 継承階層を「修正」する必要がある場合。したがって、サブクラス化されるべきであるが、何らかの理由でサブクラス化されていないタイプAありBます。その場合、からAへの暗黙の変換を定義できますB

これらは、暗黙の変換を定義することが適切な唯一のケースです。その他の変換は、急いで型の安全性と正確性の問題に遭遇します。

Tを拡張することは実際には意味がありません。Option[T]明らかに、変換の目的は単にメンバーを追加することではありません。したがって、このような変換はお勧めできません。

于 2009-11-17T16:47:09.847 に答える
1

これは、他の開発者がコードを読むときに混乱を招く可能性があるように思われます。

一般に、implicitあるオブジェクトから別のオブジェクトへのキャストを支援し、コードを乱雑にする可能性のある紛らわしいキャストコードを切り取るのに役立つようですが、変数があり、それが何らかの形で になると、Some面倒に思えます。

それがどれほど混乱するかを見るために、それが使用されていることを示すコードを入れたいと思うかもしれません。

于 2009-11-17T03:21:35.943 に答える
0

メソッドをオーバーロードすることもできます。

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
}
于 2014-03-07T16:05:03.403 に答える
-2

プリミティブ T (null にすることはできません) では機能しない可能性があることを除けば、それは私には良さそうです。特殊化されていないジェネリックは常にボックス化されたプリミティブを取得すると思うので、おそらく問題ありません。

于 2009-11-17T03:26:12.477 に答える