如果该方法只有一个或两个可以设置为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 {
....
}
显然,这里我们需要扩展 trait,同时保留原始默认值。任何涉及最初将参数设置为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
}
仍然在覆盖现有合同时,这可能是遵守原始默认值的唯一方法。