函数重载¶
规则¶
在 Lumos 中,默认情况下函数是不可重载的。如果需要在同一作用域内定义同名函数,所有参与重载的函数变体都必须显式地标记 ovl 关键字。
如果一个函数未标记 ovl,它将独占该函数名,任何后续尝试使用相同名称(无论是否标记 ovl)的操作都会导致编译错误。
标记为 ovl 的函数在进行 名称重整 时会使用特殊的实体标识 O(而非普通的 F),以便链接器和解析工具识别其重载身份。
ovl def foo(i32 a) -> unit;
ovl def foo(f32 a) -> unit; // OK: 所有参与者都标记了 ovl
def bar(i32 a) -> unit;
ovl def bar(f32 a) -> unit; // Error: 第一个定义没有标记 ovl,拒绝重载
def bar(f32 a) -> unit; // Error: 重定义
对于重载函数的搜索条件按顺序遵循以下几条规则:
- 参数数量相同
- 优先完全匹配
- 优先无损转换
- 有损隐式转换(警告)
仅返回类型差异的重载¶
Lumos 允许同名同参数列表(含泛型约束与 where 约束)在受限条件下仅通过返回类型区分重载,但只允许以下组合:
-> T-> unit
不允许出现多个不同的非 unit 返回类型(例如同时存在 -> i32 与 -> string)。
等价副作用要求¶
为保证"编译器选择哪个重载都不影响程序可观测行为",上述两种返回值重载必须具有相同副作用签名:
- 都显式标记
ovl - 纯度均为
act - 权限集合一致
- 异常行为一致(可抛异常集合、
panic行为) - 其他语义修饰一致(
async、once?/once!等)
若编译器无法证明一致性,应拒绝该组重载。
重载选择规则¶
- 值上下文(赋值、参数、
return、表达式计算):优先选择-> T - 语句上下文(结果未被消费):若存在
-> unit则选择-> unit - 若仍出现二义性,编译器拒绝推断并要求显式写法
未使用返回值错误¶
除 unit 外,任何表达式结果都必须被"使用"或"显式丢弃",否则编译错误。
视为已使用:
- 参与赋值:
val x = f(); - 作为参数:
g(f()); - 直接返回:
return f(); - 参与后续表达式:
f() + 1
视为显式丢弃:
val _ = f();
若语句位置调用返回 T 的函数且不存在 -> unit 重载,编译器报错并提示添加显式丢弃。
相关内容:函数与纯度见 函数与纯度。