Scala default parameters and null
I have a method like this:
def aMethod(param: String = "asdf") = {
...
}
If the method is called as follows, then param is given the default value "asdf":
aMethod() ...
But what I would like, is that if the method is called with null
, then the default value would also be applied:
aMethod(null) //inside the method, I can use `param` and it has the value "asdf".
Whats the best way to do this in Scala? I can think of pattern matching or a simple if
statement.
Pattern matching
def aMethod(param: String = null) {
val paramOrDefault = param match {
case null => "asdf"
case s => s
}
}
Option (implicitly)
def aMethod(param: String = null) {
val paramOrDefault = Option(param).getOrElse("asdf")
}
Option (explicitly)
def aMethod(param: Option[String] = None) {
val paramOrDefault = param getOrElse "asdf"
}
The last approach is actually the most idiomatic and readable once you get use to it.
def aMethod(param: String = null) = {
val p =
if(param == null)
"asdf"
else
param
println(p)
}
But the question must be asked: why allow null
? Would Option
be possible in your case? For this you could do:
def aMethod(param: Option[String]) = {
val p = param.getOrElse("asdf")
println(p)
}
This makes it clear that your method expects the possibility of a "null" argument.
If the method has just one or two default parameters that can be set to null
consider this pattern:
// please note that you must specify function return type
def aMethod (x:String = "asdf"):String = if (x==null) aMethod() else {
// aMethod body ...
x
}
There are some benefits:
Furthermore, consider the following scenario:
trait ATrait {
def aMethod (x:String = "trait's default value for x"):String
}
class AClass extends ATrait {
....
}
Clearly, here we need to extend the trait, whilst preserving the original default value. Any of the patterns that involve initially setting the parameter to null
followed by a check and actual default value will break the contract established by the trait:
class AClass extends ATrait {
// wrong, breaks the expected contract
def aMethod(x: String = null):String = {
val xVal = if (x == null) "asdf" else x
...
}
}
Indeed in this scenario the only way to preserve the original value from ATrait
will be:
class AClass extends ATrait {
override def aMethod (x:String):String = if (x==null) aMethod() else {
... // x contains default value defined within ATrait
}
}
However, in the scenario when there are more than one or two default parameters that can be set to null
the pattern starts getting rather messy:
// 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
}
Still when overriding an existing contract this might be the only way to honour the original default values.
链接地址: http://www.djcxy.com/p/72822.html上一篇: 全局变量在斯卡拉
下一篇: Scala的默认参数为null