是否有任何使用闭包返回 Iterator<Item = &mut T>
的函数示例?
我想编写一些Rust函数,这些函数遍历集合的内容多次,可能是向后迭代 . 单独使用 IntoIterator
是不够的,因为它通过值来消耗其参数以防止多次迭代 . 迭代器可以经常克隆,但是可变引用的迭代器 .
如果我们真的只需要对集合的确切元素进行迭代,那么我们可以将 &mut C: IntoIterator
用于所有Rust集合类型 C
. 接受RFC 2289语法,这可能如下所示:
fn batch_normalization<II: ?Sized>(v: &mut II)
where
for<'a> &'a mut II: IntoIterator<Item = &'a mut Self, IntoIter: DoubleEndedIterator + ExactSizeIterator>,
但目前的形式是compiler bug . 此外,这不允许用户使用迭代器适配器(如 map
)指定集合内容的"view" .
直观地说,我们应该使用一个在调用时重建迭代器的闭包来借用集合:
fn batch_normalization<F>(f: F)
where
F: FnMut() -> impl Iterator<Item = &mut Self> + DoubleEndedIterator + ExactSizeIterator
我们不能写那个因为(a)特征中的 impl Trait
问题尚未解决,(b)我们的 &mut Self
需要一辈子,所以我们可以写下:
fn batch_normalization<I, F: FnMut() -> I>(f: F)
where
I: Iterator<Item = BorrowMut<Self>> + DoubleEndedIterator + ExactSizeIterator
我已经尝试过各种类似的配方,但没有一个工作,主要是因为 Item
比迭代器更长 .
我们应该通过明确地将项目的生命周期绑定到 FnMut
中的 &mut self
的生命周期来解决这个问题 &'a mut C: IntoIterator<Item = &'a mut T>
. 在伪代码中:
fn batch_normalization<I, F: FnMut() -> I>(f: F)
where
I: for<'a: F::Output> Iterator<Item = &'a mut Self> + DoubleEndedIterator + ExactSizeIterator
如何从作为参数传递的闭包中实际返回 Iterator<Item = &mut T>
?应该总是使用一些 fn
指针混乱而不是闭包吗?大致:
fn batch_normalization<'a, I, V: ?Sized>(v: &mut V, f: fn(&'a mut V) -> I)
where
I: Iterator<Item = &'a mut Self> + DoubleEndedIterator + ExactSizeIterator
{
for x in f() { }
// ...
for x in f().rev() { }
}
1 回答
由于
Fn*
traits不支持将返回类型绑定到其self
参数的生命周期,因此无法使用闭包进行此操作 . 现在,Fn*
特征读了但这需要阅读这些特征
这些是不稳定的接口,因此它们最终可能会通过RFC过程进行更改,可能使用一些特殊的
'fn
生命周期语法,如FnMut() -> impl Iterator<Item = &'fn mut Self>
,或者甚至可能将参数化类型参数Args
作为Args<'fn>
. Rust internals是这个问题的正确论坛 .