Skip to main content
Fluxon 的控制结构也是表达式:分支与循环可以产生值,并参与更大表达式的求值。本章覆盖 ifwhen、循环、break/continuetry

条件分支

基本语法

if 用于按条件选择不同的表达式结果:
要点:
  • if 后跟条件表达式。
  • then 后跟条件为 true 时计算的表达式。
  • else 后跟条件为 false 时计算的表达式。
  • 整个 if ... then ... else ... 是一个表达式,可以直接作为函数返回值或赋值右侧:

多行与嵌套写法

当分支逻辑较复杂时,可以用代码块书写,并在 if 中嵌套使用:
  • 花括号 { ... } 表示一个代码块。
  • 块内可以包含多条语句,块的结果是最后一个表达式的值,或者显式 return 的值。
  • if 是表达式,可以作为更大表达式的一部分,也可以嵌套出现在 else 分支中。

多分支选择

when 提供了更灵活的多分支选择语法,支持按条件测试和按值匹配两种用法。

条件模式

在条件模式下,when 按顺序测试每个条件:
  • 花括号内部每一行是一个“条件 -> 结果表达式”。
  • 会自上而下依次计算条件表达式,返回第一个为 true 的分支右侧结果。
  • else 分支是可选分支,用于兜底情况。
  • 如果省略 else 且没有任何条件命中,则结果为 null

值匹配

在值匹配模式下,when 先对一个表达式求值,然后与各个分支左侧的值做相等比较:
  • when expr { ... } 会先计算 expr,再依次与每个分支左侧的值比较。
  • 适合枚举值、常量分支、简单状态码等场景。
  • 同样支持 else 作为兜底分支。

集合匹配

when 支持使用 in!in 检查值是否在集合、映射或区间内:
  • in <collection> 检查主题值是否在集合中
  • !in <collection> 检查主题值是否不在集合中
  • 支持列表、映射、区间等可迭代值

类型匹配

when 支持使用 is 运算符进行类型检查:
类型匹配特性:
  • 使用 is <TypeName> 进行运行时类型检查
  • 支持类型别名(不区分大小写):stringintlistmap
  • 支持完全限定类名:is java.util.ArrayList
  • null 值不匹配任何类型,会进入 else 分支
  • 可与其他匹配类型混合使用:
详见 运算符与优先级 - 类型检查

与其他表达式组合

when 是表达式,可以绑定为变量、作为函数返回值,或嵌入到更大的表达式中:

循环

Fluxon 提供 forwhile 两种循环形式,它们都可以在循环体中使用 breakcontinue

for-in 循环

for 用于遍历列表、区间或映射等可迭代值。

遍历列表

  • 语法为 for 标识符 in 可迭代表达式 { ... }
  • 在循环体中通过 &标识符 访问当前元素。
你也可以在循环中调用函数:

遍历映射(键值对)

当可迭代值是键值对集合时,你可以直接解构当前项:
  • 使用解构 (key, value) 遍历键值对。
  • 具体迭代顺序由底层集合类型决定,例如字典或环境变量。

遍历区间

区间由 a..b(闭区间)或 a..<b(左闭右开)创建:
区间表达式本身是一个值,也可以先赋给变量再用于循环:

while 循环

while 在条件为 true 时重复执行循环体:
  • 每次进入循环体之前都会计算条件表达式。
  • 条件结果为 falsenull 时循环结束。
  • 条件表达式可以引用外层变量,也可以调用函数:

终止与跳过

终止:break

break 用于提前结束当前循环:
  • 立即结束最内层forwhile
  • 循环之后的语句会继续执行。
break 也可以配合 when 或函数调用使用,只要位置在循环体内即可。

跳过:continue

continue 用于跳过当前迭代剩余的语句,直接进入下一轮:
  • 当前迭代中,continue 之后的语句不会执行。
  • 下一轮迭代从条件检查开始。
  • 在多重嵌套循环中,continue 只作用于最内层循环。

异常处理

Fluxon 提供 throwtry / catch / finally 结构来处理运行时错误。 和其他控制结构一样,try 是一个表达式,可以产生值。

抛出异常

使用 throw(expr) 可以在任意位置显式抛出异常:
在没有被 try 包裹时,throw 会中断当前脚本的执行,向外抛出一个运行时异常。 expr 的值会作为异常的消息或原因被传递到底层运行时:

作为表达式

try 是一个完整的表达式,用来包裹可能出错的代码,并在出错时给出替代值:
示例中的 &e.message 使用成员访问 .(反射)。嵌入式集成默认关闭反射访问,如需使用请参阅 成员访问(.)
求值规则概括如下:
  • 正常情况:
    • 先执行 try { ... } 块。
    • 如果没有抛出异常,try 表达式的结果就是 try 块最后一个表达式的值。
    • 如果存在 finally,仍然会在返回前执行 finally(见下文)。
  • 出错情况:
    • 如果 try 块中抛出了异常,会跳转到后续的 catch
    • 没有匹配的 catch 时,异常会继续向外传播。仅写 try { ... } 而不写 catch / finally 时,常用于“保证 finally 执行”或调试。
由于 try 是表达式,它可以出现在赋值、函数调用参数、甚至其他表达式内部:

处理异常

catch 用于捕获异常并返回一个替代值。Fluxon 支持两种常见写法:
  1. 省略异常变量:只关心出错时的兜底结果,不关心异常对象本身:
  2. 带异常变量:需要访问异常对象的详细信息,例如类型或消息:
在这两种形式中:
  • catch 块本身是一个代码块,最后一个表达式的值(或显式 return 的值)会成为整条 try 表达式在出错时的结果。
  • 如果 try 块没有抛出异常,对应的 catch 块不会执行。

最终执行

finally 用于那些不关心结果,只关心“必须执行”的逻辑,例如日志、资源释放或计时:
执行顺序为:
  1. 执行 try 块。
  2. 若发生异常,执行 catch 块;catch 的返回值作为候选结果。
  3. 不论是否发生异常,都执行 finally 块。
  4. 如果 finally 正常结束,则 try 表达式的结果为:
    • 正常情况下:try 块的结果。
    • 出错且被捕获的情况下:catch 块的结果。
只有在 finally 内部再次抛出异常时,才会覆盖原本的结果,改为向外抛出新的异常。 否则,finally 不会改变 try / catch 已经决定好的值。

链式用法与简写形式

在 Fluxon 中,可以把多个异常处理片段写成一条链,形成紧凑的错误恢复逻辑:
这与块体写法是等价的,只是把 trycatchfinally 部分写在一行上:
你可以根据脚本复杂度选择简写或块体形式:
  • 对于一两行的简单逻辑,简写更紧凑。
  • 涉及多步操作或需要访问异常对象时,推荐使用块体形式并显式写出 (e)

相关链接