在 Rust 中,const函数在其中可以放入的代码非常有限,例如for不允许循环,也不允许任何非const函数调用。我知道const函数中的堆分配存在问题,但为什么例如下面的代码无效:
fn add(a: u8, b: u8) -> u8 {
a + b
}
const A: u8 = add(1, 2);
Run Code Online (Sandbox Code Playgroud)
如果add声明为const函数,这将是有效的,所以我不明白为什么 Rust 编译器无法检测到这是有效的;所以我想我也在问为什么const函数是必要的,为什么甚至for不允许在它们内部使用循环(即使循环是)。
为什么需要 const 函数
声明常量函数是const为了告诉编译器允许从const上下文中调用此函数。Const-eval 是在一个名为miri. Miri 无法评估所有表达式,因此const功能非常有限。已接受的扩展存在跟踪问题,并且正在进行积极的工作以使它们与常量兼容。
我不明白为什么 Rust 编译器无法检测到这是有效的;
虽然技术上可行,但 Rust 团队决定反对。主要原因是语义版本控制问题。在不更改签名的情况下更改函数的主体可能会使该函数不再与 const 兼容并破坏 const 上下文中的使用。const fn是一个契约,而打破那个契约就是一个明确的破坏性改变。
以及为什么甚至不允许在它们内部使用 for 循环(即使是 while 循环)。
至于为什么for不允许循环,它们在技术上是允许的。唯一的问题是该Iterator::next方法 not const,这意味着不是某些迭代器可以执行不是 const-evaluatable 的操作。在允许 trait 方法被标记为 的语言构造const,或者能够放置const bounds 之前,你将不得不坚持使用常规loops。
const fn looop(n: usize) {
let i = 0;
loop {
if i == n { return; }
// ...
}
}
Run Code Online (Sandbox Code Playgroud)