如何在unfold实现中满足借用检查器:让闭包接收A而非&A
实现接收
A而非&A的unfold迭代器 原有的unfold实现存在局限,要求闭包必须接收&A类型的参数,而非直接接收A:
pub fn unfold<A, B>(init: A, f: impl Fn(&A) -> Option<(A, B)>) -> impl Iterator<Item = B> { let mut acc = init; std::iter::from_fn(move || { f(&acc).map(|(a, b)| { acc = a; b }) }) }
我们需要实现一个版本,让闭包直接接收A,且不依赖unsafe、Copy或其他额外约束。
可行实现方案
可以通过转移所有权的方式实现,核心是利用Option的take()方法取出当前累积值的所有权,传递给闭包后再根据返回值更新累积值:
pub fn unfold<A, B>(init: A, f: impl Fn(A) -> Option<(A, B)>) -> impl Iterator<Item = B> { let mut acc = Some(init); std::iter::from_fn(move || { acc.take().and_then(|current| { f(current).map(|(new_acc, item)| { acc = Some(new_acc); item }) }) }) }
实现逻辑说明
- 初始化时将初始值
init包装进Some,后续通过take()方法取出其所有权,避免借用冲突。 - 每次迭代时,
acc.take()会取出当前的累积值,此时acc变为None。 - 将取出的累积值传递给闭包
f:- 若
f返回Some((new_acc, item)),则把new_acc重新存入acc,并返回Some(item)作为当前迭代项。 - 若
f返回None,acc保持None,后续迭代会直接返回None,终止整个迭代过程。
- 若
这个实现完全满足需求,没有使用任何禁用特性或额外约束。
内容的提问来源于stack exchange,提问作者user1002430
相关产品推荐
相关产品推荐

