这是预期的行为还是编译器错误?
以下代码无法编译。valuesinMyStruct是一个Option因为Vec::new不是 const fn - 但它Option::None是常量(但它仍然不能编译)。
type MyFun = fn(input: u32) -> u32;
struct MyStruct {
values: Option<Vec<MyFun>>,
}
impl MyStruct {
pub const fn init() -> Self {
Self { values: None }
}
}
fn main() {
MyStruct::init();
}
Run Code Online (Sandbox Code Playgroud)
error[E0723]: function pointers in const fn are unstable
--> src/main.rs:9:24
|
9 | Self { values: None }
| ^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
Run Code Online (Sandbox Code Playgroud)
使用 newtype ( Wrapped) 解决了这个问题。这感觉很奇怪,因为两个示例都是相同的(至少生成的二进制文件应该是相同的)。这种行为是有意的还是一个错误?
这有效:
type MyFun = fn(input: u32) -> u32;
struct Wrapped(Vec<MyFun>);
struct MyStruct {
values: Option<Wrapped>,
}
impl MyStruct {
pub const fn init() -> Self {
Self { values: None }
}
}
fn main() {
MyStruct::init();
}
Run Code Online (Sandbox Code Playgroud)
TLDR:一个错误,但不是你暗示的那个。我们过于积极地为 const fn 中的未来功能敞开大门。
您遇到的错误是为了防止用户编写类似的功能而创建的
const fn foo(f: fn()) {}
Run Code Online (Sandbox Code Playgroud)
因为不可能以f可调用的方式使用。以下功能目前是非法的。
const fn foo(f: fn()) { f() }
Run Code Online (Sandbox Code Playgroud)
在稳定的时候const fn我们不确定它是否应该合法,所以我们先发制人地禁止fn了const fn. 在 const fn 中创建函数指针也是如此。所以
const fn foo() {
let f: fn() = some_function;
}
Run Code Online (Sandbox Code Playgroud)
是被禁止的,因为我们想保持开门许可
const fn foo() {
let f: fn() = some_function;
f();
}
Run Code Online (Sandbox Code Playgroud)
如果你扩展你的用例的代码,你会得到类似的东西
pub const fn init() -> Self {
let values: Option<fn(u32) -> u32> = None;
Self { values }
}
Run Code Online (Sandbox Code Playgroud)
你是对的,这是一个错误。虽然不是由于包装和非包装版本之间的差异,而是因为它们None从未真正创建过函数指针。我们只是决定在检查中过于激进,以免错过任何东西。虽然我们可能只想在 const fn 中实现函数指针,但绝对可以在这里创建更好的分析。
包装和非包装版本之间存在差异的原因是我们希望允许
const fn foo(f: fn()) { f() }
Run Code Online (Sandbox Code Playgroud)
但不是
const fn foo(wrapper: Wrapper) { (wrapper.f)() }
Run Code Online (Sandbox Code Playgroud)
因为后者没有在 API 中显示函数指针,所以我们不能做任何魔术来确保函数指针指向一个 const fn。
包装和非包装版本之间的差异可能足以令人困惑,迫使我们放弃我们可以fn如上所述只调用const fn 中的指针并为 const fn 中的指针提出新方案的想法fn。
| 归档时间: |
|
| 查看次数: |
312 次 |
| 最近记录: |