Scala的默认参数为null

我有这样的方法:

def aMethod(param: String = "asdf") = {
    ...
}

如果方法调用如下,那么param被赋予默认值“asdf”:

aMethod() ...

但我想要的是,如果方法被调用为null ,那么默认值也会被应用:

aMethod(null)  //inside the method, I can use `param` and it has the value "asdf".

在Scala中做这件事最好的方法是什么? 我可以考虑模式匹配或简单的if语句。


模式匹配

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"
}

最后一种方法实际上是一种习惯于最习惯和可读的方法。


def aMethod(param: String = null) = { 
  val p = 
    if(param == null)
      "asdf"
     else
       param

  println(p) 
}

但是这个问题必须被问到:为什么允许null ? 将Option可以在您的情况? 为此你可以这样做:

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

这清楚地表明你的方法期望有一个“空”参数的可能性。


如果该方法只有一个或两个可以设置为null默认参数,请考虑以下模式:

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

有一些好处:

  • 方法定义清楚地表明了参数的默认值。
  • Scala工具可以选择正确的默认值,包括ScalaDoc。
  • 没有必要定义一个额外的值来代替方法体内的原始参数 - 更少的错误空间,更容易推理。
  • 该模式非常简洁。
  • 此外,请考虑以下情况:

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

    显然,在这里我们需要扩展特质,同时保留原始的默认值。 任何涉及最初将参数设置为null并随后进行检查和实际默认值的模式都会破坏由特征建立的合约:

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

    事实上,在这种情况下,保持ATrait原始价值的唯一方法是:

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

    但是,在有多个或两个可以设置为null的默认参数的情况下,模式开始变得相当混乱:

    // 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
    }
    

    仍然在覆盖现有合同时,这可能是兑现原始默认值的唯一方法。

    链接地址: http://www.djcxy.com/p/72821.html

    上一篇: Scala default parameters and null

    下一篇: How to override apply in a case class companion