2016-04-26 48 views
2

當我編寫以下內容時,IntelliJ的scalastyle讓我非常不高興。它不喜歡我寫回報。scala避免返回,同時仍然短迭代

def hasAnnotation(symbol: Symbol, annotation: Type): Boolean = { 
    for (a <- symbol.annotations) { 
    if (a.tpe =:= annotation) return true // AVOID USING RETURN!!! 
    } 
    false 
} 

爲什麼要加回歸邪惡?

我怎樣才能快捷迭代沒有返回?

+1

這將是很好,如果答案澄清爲什麼'易碎「被認爲是邪惡的。 https://github.com/scala/scala/blob/v2.11.8/src/library/scala/collection/TraversableLike.scala#L130關於https://github.com/scala/scala/blob/v2。 11.8/src/library/scala/collection/TraversableOnce.scala#L90 –

+0

這裏有一些討論http://stackoverflow.com/questions/2742719/how-do-i-break-out-of-a-loop-in-斯卡拉 – user48956

+0

是的,如下鏈接,但沒有說明我的簡單頭腦。 –

回答

3

nattyddubbs有一個很好的實現你的函數沒有返回,但我可以補充一點,爲什麼intellij警告你他們。

基本上return在scala中的工作方式與您所期望的略有不同 - jetbrains的工作人員知道這一點,並且添加了警告以確保您真的想要返回。

問題是它返回調用方返回出現的方法...不是函數。看到這一點,最好的地方是在匿名的功能,例如,假設你有一個函數來彙總列表

scala> def summer(as: List[Int]): Int = as.foldRight(0)((i,j) => i + j) 

scala> summer(List(33, 42, 99)) 
res2: Int = 174 

酷。如果你使用回報會發生什麼?

scala> def summer(as: List[Int]): Int = as.foldRight(0)((i,j) => return i + j) 

scala> summer(List(33, 42, 99)) 
res3: Int = 99 

功能的含義已經完全改變......你可能不會想到是

OK你可能永遠不會寫這樣一個簡單的函數返回,但你可以很容易地做到它在一個更復雜的Lambda和結了結果,你不要指望

羅布·諾里斯寫了一篇很好的博客文章中階here回報這實在是值得一讀

+1

是一個很好的答案。我的心被炸燬了。 – user48956

+0

鏈接的博客沒有提供任何疏漏的例子,因此可以破解。 –

11

一個做你請求的功能更強大的方法是

def hasAnnotation(symbol: Symbol, annotation: Type) = 
    symbol.annotations.exists(_.type =:= annotation) 

當發現滿足謂詞的第一個項目這將短路。迴歸不是邪惡的,它更重要。 Here's另一篇文章的鏈接,談論返回一個循環

+0

鏈接的答案使易碎成爲一個子選項。它應該是「被stdlib祝福」或被證明是有害的。 –