簡體   English   中英

無限循環似乎混淆了Scala的類型系統

[英]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)
}

根據SLSwhile循環的執行方式與:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM