通常情況下,函數的參數是傳值參數;即參數的值在它被傳遞給函數之前被確定。但是,如果我們需要編寫一個接收參數不希望馬上計算,直到調用函數內的表達式才進行真正的計算的函數。對於這種情況,Scala提供按名稱參數調用函數。
示例代碼如下:
結果:
在代碼中,如果定義函數的時候,傳入參數不是傳入的值,而是傳入的參數名稱(如代碼中使用t: => Long而不是t: Long),在調用該函數時,不會立即執行和參數有關的計算,而是到參數真正使用到的時候才進行計算。
結果說明:主函數調用delayed函數后,並不立即執行參數(time()函數的結果),而是跳過,直接執行delayed函數的第一行,到第二行真正使用到t時,才執行time()函數獲取t的值,故有上述結果。
如果將t: => Long改成t: Long,則按照值傳遞進行計算,結果如下:
此時主函數調用了delayed函數后就直接先執行time()函數獲取t的值
另一個示例代碼如下:
這里調用了一個log函數,傳入的參數中有1/0,按理說應該會報異常,但實際結果卻是代碼順利的執行完成。為什么呢?這是因為我們在定義log函數的時候使用了“按名稱傳遞參數”,只有到實際執行參數相關的計算時才會檢查是否有異常。而代碼中if(logEnable) println(msg)這一行代碼實際根本就不會執行,自然也就不會存在檢查異常的問題了
如果將msg: =>String改為msg: String,則執行代碼就會報錯
因為在執行到log(MSG +1 / 0)這一句時就直接計算了1/0,自然就會報錯了
使用“按名稱傳遞參數”方式的優點是:1.減少不必要的計算; 2.減少異常