如果方法只有一個或兩個默認的參數可以設置爲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