2012-03-15 7 views
23

私はこのような方法が持っています私は、メソッドがnullで呼び出された場合、デフォルト値も適用されます。Scalaのデフォルトパラメータとnullは

Scalaでこれを行うにはどうすればいいですか?私はパターンマッチングや単純なifステートメントを考えることができます。

答えて

46

パターンマッチング

def aMethod(param: String = null) { 
    val paramOrDefault = param match { 
     case null => "asdf" 
     case s => s 
    } 
} 

オプション(暗黙的に)

def aMethod(param: String = null) { 
    val paramOrDefault = Option(param).getOrElse("asdf") 
} 

オプション(明示的に)

def aMethod(param: Option[String] = None) { 
    val paramOrDefault = param getOrElse "asdf" 
} 

最後のアプローチは、実際には、ほとんどの慣用句、読み取り可能ですそれ。

+1

オプションに暗黙的に変換する方法はありますか?確かに私は自分のdefを書くことができましたが、すでにAPIに1つありますか? –

+4

@ JohnSmith:暗黙のdef obj2Option [T](t:T)= Option(t) 'のようなものですか?私はこれが標準的な暗黙的な変換の一部になるにはあまりにも壊れやすい/危険であると思いますが、そのようなことはわかりません。 –

+0

@TomaszNurkiewicz私の答えを見てください。この解決法は、Scalaの開発ツールに悪影響を及ぼし、継承が関わるたびにコードを破る可能性があります。 –

5

しかし、質問する必要があります:なぜnullを許可するのですか?あなたの場合、Optionは可能でしょうか?あなたが行うことができ、このために:

def aMethod(param: Option[String]) = { 
    val p = param.getOrElse("asdf")  
    println(p) 
} 

これは、それを明確にあなたの方法は、「ヌル」引数の可能性を期待していることになります。あなたが使用し得れば

5

方法はnullに設定することができますちょうど1か2つのデフォルトのパラメータは、このパターンを検討している場合:

// please note that you must specify function return type 
def aMethod (x:String = "asdf"):String = if (x==null) aMethod() else { 
    // aMethod body ... 
    x 
} 

いくつかの利点があります。

  • メソッドの定義は明確にパラメータのデフォルト値を示し、値。
  • 正しいデフォルト値は、ScalaDocを含むScalaツールで選択できます。
  • メソッドの本体内の元のパラメータを置き換えるために追加の値を定義する必要はありません。間違いが起こりにくい理由が簡単です。
  • パターンはかなり簡潔です。私たちは、元のデフォルト値を維持しながら、形質を拡張する必要があり、ここで、明らかに

    trait ATrait { 
        def aMethod (x:String = "trait's default value for x"):String 
    } 
    
    class AClass extends ATrait { 
        .... 
    } 
    

はさらに、次のシナリオを検討してください。このシナリオでは、実際に

class AClass extends ATrait { 
    // wrong, breaks the expected contract 
    def aMethod(x: String = null):String = { 
     val xVal = if (x == null) "asdf" else x 
     ... 
    } 
} 

ATraitから元の値を維持するための唯一の方法:最初に特性によって確立された契約が解除されますチェックし、実際のデフォルト値が続くnullにパラメータを設定することを伴うパターンのどれ次のようになります。しかし、シナリオにnullに設定することができます1つのまたは2つ以上のデフォルトパラメータがある場合

class AClass extends ATrait { 
    override def aMethod (x:String):String = if (x==null) aMethod() else { 
    ... // x contains default value defined within ATrait 
    } 
} 

パターンはかなり厄介な取得を開始:

それでも
// two parameters 
def aMethod (x:String = "Hello",y:String = "World"):String = 
    if (x==null) aMethod(y=y) else 
    if (y==null) aMethod(x=x) else { 
    // aMethod body ... 
    x + " " + y 
} 

// three parameters 
def aMethod (x:String = "Hello",y:String = " ",z:String = "World"):String = 
    if (x==null) aMethod(y=y,z=z) else 
    if (y==null) aMethod(x=x,z=z) else 
    if (z==null) aMethod(x=x,y=y) else { 
    // aMethod body ... 
    x + y + z 
} 

既存の契約をオーバーライドするとき、これは元のデフォルト値を尊重するための唯一の方法かもしれません。

+0

私はあなたのアプローチ(と正当化)が本当に好きです。私はそれをより多くのポイントを与えることができますしたい。私はそれが答えでなければならないと思うからです。ありがとう。 – Neil

関連する問題