我有这样的方法:
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
语句。
答案 0 :(得分:51)
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 :(得分:5)
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”参数的可能性。
答案 2 :(得分:5)
如果该方法只有一个或两个默认参数可以设置为null
,请考虑以下模式:
// please note that you must specify function return type
def aMethod (x:String = "asdf"):String = if (x==null) aMethod() else {
// aMethod body ...
x
}
有一些好处:
此外,请考虑以下情况:
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
}
仍然在覆盖现有合同时,这可能是兑现原始默认值的唯一方法。