【问题标题】:Is it possible to write a const function that folds over an iterator?是否可以编写一个折叠迭代器的 const 函数?
【发布时间】:2019-04-02 16:10:50
【问题描述】:

是否可以编写一个折叠迭代器的 const 函数?当我尝试时:

const fn foo(s: &str) -> u64 {
    return s.chars().fold(0, |accumulator, char| -> u64 {
        return accumulator ^ (char as u64);
    });
}

我得到一个编译器错误:

error: function pointers in const fn are unstable
 --> src/lib.rs:2:30
  |
2 |       return s.chars().fold(0, |accumulator, char| -> u64 {
  |  ______________________________^
3 | |         return accumulator ^ (char as u64);
4 | |     });
  | |_____^

我认为我的匿名函数 |x, y| -> x { ... } 是作为指向 fold() 的函数指针传递的,这就是导致错误的原因。

是否有某种 const lambda 可以在这里传递给 fold,或者我可以只使用 for 循环并将结果累积到一个可变变量中,然后从 foo 函数返回?我完全没有 Rust 经验...

【问题讨论】:

    标签: rust constants


    【解决方案1】:

    不,你不能在稳定的 Rust 1.33 中这样做。您需要将函数设为非 const:

    fn foo(s: &str) -> u64 {
        s.chars().fold(0, |accumulator, char| {
            accumulator ^ (char as u64)
        })
    }
    

    请注意,我删除了显式的 return 关键字和闭包返回类型,使其成为惯用的。

    另见:


    如果你在夜间 Rust 中尝试这样做:

    #![feature(const_fn)]
    
    const fn foo(s: &str) -> u64 {
        s.chars().fold(0, |accumulator, char| {
            accumulator ^ (char as u64)
        })
    }
    

    你会得到一个不同的错误:

    error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
     --> src/lib.rs:4:5
      |
    4 |     s.chars().fold(0, |accumulator, char| {
      |     ^^^^^^^^^
    
    error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
     --> src/lib.rs:4:5
      |
    4 | /     s.chars().fold(0, |accumulator, char| {
    5 | |         accumulator ^ (char as u64)
    6 | |     })
      | |______^
    

    调用Iterator::fold 需要对the original const fn RFC 911 进行多个扩展才能实现。例如,原始 RFC 明确禁止:

    特征、特征实现及其方法不能是const

    由于闭包是作为由 trait 支持的泛型实现的,因此出于同样的原因,我不会立即看到它们可以很容易地实现。

    【讨论】:

    • 感谢您的彻底编辑。你知道将来是否有提议的解决方案让我们在 const 函数中使用高阶函数?我查看了您链接的最后一个问题中链接的 RFC 线程,但我不明白。
    猜你喜欢
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-29
    • 2015-09-04
    • 2014-08-31
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    相关资源
    最近更新 更多