[英]Infinite loop seems to confuse Scala's type system
這是一個人工玩具示例,演示了我的問題:
def sscce(): Int = {
val rand = new Random()
var count = 0
while (true) { // type mismatch; found: Unit, required: Int
count += 1
if (rand.nextInt() == 42) return count
}
}
我怎樣才能幫助編譯器理解這個方法總會返回一個Int
?
我知道上面的玩具示例很容易被重構以完全擺脫無限循環,但我真的希望在我的實際代碼中有無限循環。 相信我;)
總是返回Int
:
def sscce(): Int = {
val rand = new Random()
var count = 0
while (true) {
count += 1
if (rand.nextInt() == 42) return count
}
count // <-- this
}
你也可以這樣做:
def foo: Int = {
...
while(true) {
... return ...
}
throw new IllegalStateException // unreachable
}
這將是類型檢查,因為throw
的類型是Nothing
,這是Int
的子類型。
看到這個問題 。 while循環不返回值。 即它們返回Unit
,它是函數中的最后一個語句。 所以,定義說它返回一個Int
但它實際上返回Unit
因此返回了類型錯誤。 @ ionut的答案通過將count
作為最后一個語句返回來修復類型錯誤,或者這是一個遞歸方法。
def sscce(): Int = {
val rand = new Random()
def ssccer(count: Int): Int = {
if(rand.nextInt == 42) return count
else ssccer(count + 1)
}
ssccer(0)
}
根據SLS , while
循環的執行方式與:
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
if (cond) { body ; whileLoop(cond)(body) } else {}
即,它返回Unit
。 因此編譯器將while
視為sscce()
的最后一個語句,因此假設您正在嘗試返回Unit
。 我不認為它很聰明地意識到return count
最終將總是返回Int
。
簡單的解決方案是遵循@Brian或@IonutGStan的建議,並強制它返回count
,無論它是否真正需要它。
從代碼質量的角度來看,放棄while(true)
循環並將其替換為更具可讀性的東西將是一件好事。 作為一個很好的副作用,它也解決了你的問題:
def sscce(): Int = {
val rand = new Random()
var count = 1
while (rand.nextInt() != 42) {
count += 1
}
count
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.