如果方法只有一个或两个默认的参数可以设置为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
}
仍然覆盖现有合同时,这可能是兑现原始默认值的唯一方法。
有没有办法隐式转换为选项?当然,我可以写自己的def,但API中是否有一个? – 2012-03-15 20:32:37
@JohnSmith:你的意思是这样的:'implicit def obj2Option [T](t:T)= Option(t)'?我认为,作为标准隐式转换的一部分,这太脆弱/危险了,我不知道这样做。 – 2012-03-15 20:38:01
@TomaszNurkiewicz请看我的回答,因为这个解决方案在仔细检查后会对Scala开发工具产生负面影响,并且在涉及继承时可能会破坏代码。 – 2012-03-15 23:17:48