在scala中使用return的話,編譯的時候會提示
the latest statement is method is automatically returned, use of th return keyword is redundant.
這個警告是說最後一個語句的結果會自動返回,使用return關鍵字是多餘的。
在查閱之後,整理了以下幾點不建議使用return關鍵字的原因
要寫函數而不是指令
函數式編程的一個重要理念就是儘量使代碼由無狀態的函數構成,而不是給計算機發出指令。
簡單地講,函數式編程差不多追求的就是代碼塊[函數]寫得和數學表示差不多,這樣才清晰,比如數學中:
f(x) = x + 1
對應的Scala代碼爲:
def f(x:Int) = x + 1
def f(x:Int):Int = return x + 1
從Scala兩個寫法中分別使用和不使用return地表達式來看,除了def關鍵字和對參數地類型標記外,不使用return看起來就是函數,而使用了return更像指令
使用return會影響類型推斷
Scala中的類型推斷機制會自動將最後一個表達式的類型作爲返回類型,函數能自動識別結果爲某類型。
如果使用了return語句,就會破壞類型推斷機制,需要顯示註明返回類型。
使用return返回含義模糊
有時使用return會讓代碼的返回更加混亂,這個歧義主要產生於return到底返回到哪一層函數
def add(n:Int,m:Int):Int = return n+m
def sum1(ns:Int*):Int = ns.foldLeft(0)(add)
上述代碼中,目前來看還沒什麼問題,但是寫成下面的形式
def sum2(ns:Int*):Int = ns.foldLeft(0)((n,m) => return n+m)
直觀感受,上面兩種寫法是一致的,但事實上sum1(1,2,3) = 6,sum2(1,2,3) = 1
原因就是return語句會直接讓它出現的函數返回,也就會直接break foldLeft的循環返回結果
再看另一個例子:
def foo:Int = {
val sumR:List[Int] => Int = _.foldLeft(0)((n,m) => return n + m)
sumR(List(1,2,3)) + sumR(List(4,5,6))
}
首先定義一個匿名函數,在調用匿名函數的時候,相當於return語句出現在了foo函數中,因此foo() = 1
這裏可以提到一個點,anonymous function中的return
scala是用拋出異常的方式來實現anonymous func中的return的,anonymous function中的return是以NonLocalReturnException實現的
關於anonymous function中的return具體的解釋如下網站:
https://www.jianshu.com/p/2053634328d3
處理方法
實際開發中我們會經常遇到貌似必須使用return的時候
首先,scala既然提供了return關鍵字,說明並不是禁止使用的,而是需要考慮是否必須這麼做。在Scala認爲,所有的需要使用return來break的循環,都是可以通過轉化爲遞歸來替代的,並且性能方面Scala也專門爲遞歸做了優化。