Scala—scala中不建議使用return

在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也專門爲遞歸做了優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章