兼容性与限制

这些是「能编译,但和普通 Rust 的语义不一样」的地方。写节点图之前先过一遍,能省掉不少调试。

运算溢出

i32 的四则运算默认自动溢出,也就是直接映射到原生的运算节点,不做溢出检查。所以别指望靠溢出 panic 来发现错误,该用 checked_* / saturating_* 的地方要自己判。

整数除法

两种情况都不会 panic,而是走各自的原生节点行为。

扁平化局部变量

局部变量(包括参数和返回值)里的元组、闭包、事件会被递归展开成一维的变量列表。这是为了让节点图支持多个返回值 —— 一个 fn 返回 (f32, f32),在图上就是两个输出引脚,而不是一个「元组」类型的引脚。副作用:你在 Rust 里写的元组、闭包,编译后不再是一个整体,而是被拆成的若干个局部变量。

内部可变性

不支持 Cell 等内部可变性。将来可能会支持 RcRefCell 和 RcUnsafeCell,目前没有。需要共享可变状态时,用 &mut 借用(见下)。

可变借用

&mut 只支持两种目标:整体借一个标量局部变量(i32、句柄之类),或者借元组的某个元素。整体借一个元组局部变量不行 —— 元组被展平成多个独立变量,没有「整体」可借,编译时报 Only local singleton can be ref mut。结构体字段的可变借用(&mut p.a)也还没实现。
let mut i = 1;
let r = &mut i;        // 可以

let mut v = (1, 2);
let r = &mut v.0;      // 可以:借元素
let r = &mut v;        // 不行:借整个元组
改元组成员本来也不需要取引用,直接赋值即可:
let mut pair = (1, 2);
pair.0 = 10;
(有例外:若引用没逃逸出去,rustc 的 MIR 优化可能先把 &mut 消掉,让整体借用元组「侥幸」编过 —— 换了写法就会崩,别依赖。)