`filter(func)` 和 `filter(|x| func(x))` 有什么区别?

fin*_*ian 5 iterator rust

filter(|x| func(x))和 和有什么区别filter(func)?也许一个好的起点是了解如何filter(func)使用类似于filter(|x| func(x)). 我的代码如下所示:

fn filter_out_duplicates(vec_of_vecs: Vec<Vec<u8>>) -> Vec<Vec<u8>> {
  vec_of_vecs
     .into_iter()
     .filter(all_unique)
     .collect()
}

pub fn all_unique<T>(iterable: T) -> bool
where
   T: IntoIterator,
   T::Item: Eq + Hash,
{
   let mut unique = HashSet::new();
   iterable.into_iter().all(|x| unique.insert(x))
}
Run Code Online (Sandbox Code Playgroud)
fn filter_out_duplicates(vec_of_vecs: Vec<Vec<u8>>) -> Vec<Vec<u8>> {
  vec_of_vecs
     .into_iter()
     .filter(all_unique)
     .collect()
}

pub fn all_unique<T>(iterable: T) -> bool
where
   T: IntoIterator,
   T::Item: Eq + Hash,
{
   let mut unique = HashSet::new();
   iterable.into_iter().all(|x| unique.insert(x))
}
Run Code Online (Sandbox Code Playgroud)

但是如果我使用|x| all_unique(x). 我知道破译编译器错误是解决 Rust 问题的推荐方法,但我发现这个错误非常难以理解。

我发现一个讨论似乎更多的是对错误的同情,而不是解释强制,但我发现Rustonomicon 中关于强制的章节太短,无法提供理解。

Cha*_*man 6

本案与胁迫无关。这是晚绑定生命周期与早绑定生命周期的另一种情况。

Rust 有两种生命周期:早期绑定晚期绑定。差异归结为决定使用哪个生命周期。

对于较晚的束缚生命,您会获得更高等级的特质束缚- 类似于for<'a> fn(&'a i32)。然后,仅在调用该函数时才选择生命周期。

另一方面,对于早期束缚的生命周期,你会得到fn(&'some_concrete_lifetime i32)。生命周期可以推断,有时可以省略,但它确实存在。并且必须在我们决定函数指针/项的类型时决定。

filter()期望 HRTB 函数,即具有晚绑定寿命。这是因为 的脱糖FnMut(&Self::Item) -> bool它是 中的界限)filter()for<'a> FnMut(&'a Self::Item) -> bool,或者,如果您愿意的话,for<'a> FnMut<(&'a Self::Item,), Output = bool>是 。

all_unique()然而,你的是通用的T: IntoIterator。如果我们设置T = &'a Vec<u8>,那么'a就是提前绑定。这是因为泛型参数的生命周期总是早期绑定的——本质上,因为我们不能后期绑定泛型参数,因为 Rust 中没有办法表达for<T>,因为泛型类型参数是单态的,所以这通常是不可能的。

因此,如果我们揭示省略的生命周期,您想要满足特征界限fn(&'some_lifetime Vec<u8>) -> bool: for<'all_lifetimes> FnMut(&'all_lifetimes Vec<u8>) -> bool,而这个界限是错误的。这就是您看到的错误的原因。

然而,如果我们使用闭包,我们就会生成一个特定于 type 的闭包&'lifetime Vec<u8>。由于它在类型上不是通用的,因此生命周期可以被后期绑定。

  • @Holloway 有,如果它没有内联。但它可能会是,如果不是,性能影响可能可以忽略不计。 (2认同)