当前位置: 首页 > 知识库问答 >
问题:

是否可以编写一个在迭代器上折叠的const函数?

颛孙和颂
2023-03-14

可以编写一个可以折叠到迭代器上的常量函数吗?当我尝试时:

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 |-

这里是否有某种常量lambda可以传递给fold,或者我可以使用for循环,将结果累加到一个可变变量中,然后从foo函数返回?我绝对没有生锈的经验。。。


共有1个答案

刘绍晖
2023-03-14

不,你不能在稳定锈1.59中这样做。您需要将函数设置为非常量:

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

注意我删除了显式返回关键字和闭包返回类型以使其惯用。

另见:

  • 在使用AtomicUsize::new时,常量fns是一个不稳定的功能
  • 为什么不能使用返回编译时常量作为常量的函数
  • 在Rust中,有可能在编译时计算递归函数吗

如果你尝试在夜间生锈:

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

您将得到一个不同的错误:

error[E0015]: cannot call non-const fn `core::str::<impl str>::chars` in constant functions
 --> src/lib.rs:2:7
  |
2 |     s.chars().fold(0, |accumulator, char| {
  |       ^^^^^^^
  |
  = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const fn `<Chars as Iterator>::fold::<u64, [closure@src/lib.rs:2:23: 4:6]>` in constant functions
 --> src/lib.rs:2:15
  |
2 |       s.chars().fold(0, |accumulator, char| {
  |  _______________^
3 | |         accumulator ^ (char as u64)
4 | |     })
  | |______^
  |
  = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

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

trait、trait实现及其方法不能是const

由于闭包是作为由traits支持的泛型实现的,因此我不认为出于同样的原因可以轻松实现它们。

 类似资料:
  • Prism.js 可以做到代码的高亮,和行号的展示: 请问是否可以做到代码的折叠呢?

  • 我想表达以下Haskell代码,只使用函子代数(即-不依赖于任何特定的容器类型,如): 对于可折叠/可遍历的函子是否有一个一般的first和rest概念? 是否有一种公认的惯用方法,仅使用函子代数,来移动可折叠/可遍历函子的内容?(请注意,上面的计算可以用英语描述为:“从右边移入一个值,然后将左边的值加回新的第一个值。”)

  • 问题内容: 我有一个在HashMap上使用的迭代器,并且保存并加载了该迭代器。有没有办法用迭代器在HashMap中获取上一个密钥?(java.util.Iterator) 更新资料 我将其另存为Red5连接中的属性,然后将其重新加载以在我停止的地方继续工作。 另一个更新 我正在遍历HashMap的键集 问题答案: 正如其他人指出的那样,它并不直接,但是例如,如果您需要访问一个先前的元素,则可以轻松

  • 是否可以自定义Visual Studio代码中代码折叠的工作方式? 我使用一种通用模式来跨各种不同的文档类型定义代码区域。 > 因此,对于XML,我用< code >包装文本部分 对于c#,我使用来, 对于TypeScript/Javascript,我使用< code>/* #region */和< code>/* #endregion */。 在full Visual Studio(而不是VS

  • 问题内容: 如果我有一个包含的列表,并且想编写一个迭代器,以便对以’a’开头的元素进行迭代,那么我可以编写自己的迭代器吗?我怎样才能做到这一点 ? 问题答案: 当然。迭代器只是接口的实现。如果您使用中的现有可迭代对象(例如),则需要对其进行子类化并覆盖其功能,以便返回自己的对象,或者提供一种在特殊实例中包装标准迭代器的方法(具有被更广泛使用的优势)等。

  • 问题内容: 我想知道是否可以在Swift中编写内联汇编。 我知道在Objective-C中,您可以使用如下代码: 但是在Swift中似乎无法使用 。 有谁知道如何使用,如果可能的话。我没有找到任何关于它的信息,所以我认为这是一个很好的问题。 问题答案: 要扩展Robert Levy所说的内容,您可以只使用Swift / Obj-C互操作功能,并编写一个可以处理ASM内容的Obj- C类,然后可以从