E4108

E4108#

循环需要产生一个值;在当前语法中,请添加 nobreak 分支。

当编译器根据 for 循环的上下文(例如函数的返回类型)推断出 for 循环应该产生一个非 Unit 值,但循环缺少用于提供该值的分支时,就会发生此错误。在当前 MoonBit 语法中,该分支写作 nobreak

在 MoonBit 中,当 for 循环用于需要值的上下文中(例如,当函数返回非 Unit 类型时),循环必须有一个 nobreak 分支,用于指定当循环正常完成时应返回的值。这是因为:

  1. 循环体本身不能产生值(与 loop 表达式不同)

  2. 如果没有 nobreak 分支,就无法确定当循环正常完成而没有中断时应该返回什么值。

这通常发生在两种情况下:

  • 当 for 循环是返回非 Unit 类型的函数中的最后一个表达式时

  • 当 for 循环的结果被赋值给一个变量或用于一个需要非 Unit 值的表达式时

错误示例#

///|
pub fn f(x : Int) -> Int {
  for i = 0, acc = 0; i < x; i = i + 1, acc = acc + i {
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: The for loop is
    //                                                      not expected to yield a
    //                                                      value, please add an
    //                                                      `else` branch.
  }
}

///|
pub fn g(x : Int) -> Int {
  for i in 0..<=x {

  }
}

建议#

要修复此错误,您可以:

  • 向 for 循环添加一个 nobreak 分支:

///|
pub fn f(x : Int) -> Int {
  for i = 0, acc = 0; i < x; i = i + 1, acc = acc + i {

  } nobreak {
    acc
  }
}
  • 如果您不需要从循环中返回值,请将函数的返回类型更改为 Unit

///|
pub fn g(x : Int) -> Unit {
  for i in 0..<=x {
    ignore(i)
  }
}