rust - 为什么我会收到错误 "function pointers in const fn are unstable",但在用新类型包装后它会消失?

标签 rust constants

这是预期行为还是编译器错误?

以下代码无法编译。 MyStruct 中的 values 是一个 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();
}

Playground

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

使用新类型(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();
}

Playground

最佳答案

TLDR:一个错误,但不是您所暗示的错误。我们过于积极地为 const fn 的 future 功能敞开大门。

您遇到的错误是为了防止用户编写如下函数而创建的

const fn foo(f: fn()) {}

因为不可能使用f以可调用的方式。以下功能目前是非法的。

const fn foo(f: fn()) { f() }

稳定时const fn我们不确定它是否应该合法,所以我们先发制人地禁止 fn const fn 中的指针.在 const fn 中创建函数指针也是如此。所以

const fn foo() {
    let f: fn() = some_function;
}

是禁止的,因为我们想为允许而敞开大门

const fn foo() {
    let f: fn() = some_function;
    f();
}

如果你扩展你的用例代码,你会得到类似的东西

pub const fn init() -> Self {
    let values: Option<fn(u32) -> u32> = None;
    Self { values }
}

你是对的,这是一个错误。虽然不是由于包装和非包装版本之间的差异,但因为 None从来没有真正创建一个函数指针。我们只是决定在检查中过于激进,以免错过任何东西。在这里创建更好的分析绝对是可能的,尽管我们可能只想在 const fn 中实现函数指针。

包装和非包装版本之间存在差异的原因是我们希望允许

const fn foo(f: fn()) { f() }

但不是

const fn foo(wrapper: Wrapper) { (wrapper.f)() }

因为后者在 API 中没有显示函数指针,所以我们不能做任何魔术来确保函数指针指向一个 const fn。

包装版本和非包装版本之间的区别可能令人困惑,足以迫使我们放弃我们可以调用 fn 的想法。 const fn 中的指针如上所述,并为 fn 提出了一个新方案。 const fn 中的指针。

关于rust - 为什么我会收到错误 "function pointers in const fn are unstable",但在用新类型包装后它会消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62440982/

相关文章:

multithreading - 如何跨线程共享包含发送方和接收方字段的结构?

android - Android中一些Paint常量的含义

javascript - 我可以在javascript中的键值对对象中使用常量值吗

带有来自另一个常量数组的变量的常量数组

c++ - 为什么按值传递而不是按常量引用传递?

rust - 无法在 Rust 中为二叉搜索树构建删除函数,因为借用的值不够长

python - 复制的套接字没有被腌制

c - 指向数组类型的指针,或者添加 "array decay to pointer"、 "typedef"、 "const"和 "*"时 "&"发生了什么

rust - 为什么我的自定义格式化程序实现忽略了宽度?

process - 无法通过管道多次传入或传出生成的子进程