带参数的过滤器迭代器
Filter iterator with arguments
我想在多个结构方法中调用自定义过滤器,但它应该能够以某种方式访问结构的某个 属性。
这是我目前拥有的一个基本示例:
struct Collection {
elements: Vec<isize>,
scope: isize
}
impl Collection {
fn action1(&self) {
for e in (&self.elements).iter().filter(Collection::filter) {
println!("do something ...");
}
}
fn action2(&self) {
// filter and do something with the elements
}
fn action3(&self) {
// filter and do something with the elements
}
fn filter(cur: &&isize) -> bool {
// Determine if current element needs to be filtered based on the scope value
true
}
}
fn main() {
let c = Collection { elements: vec![1, 2, 3, 4, 5, 6, 7, 8], scope: 2 };
c.action1();
c.action2();
}
我知道我可以直接将闭包/块作为参数传递,但这意味着要跨多个方法复制过滤器逻辑,这是我想避免的。
如果能够做到以下几点就好了:
fn filter(&self, cur: &&isize) -> bool {
}
然而,这不会编译,很可能是因为它实际上是一个方法,而不是一个函数。
如果函数 returns a closure,这也许是可行的,但我无法让过滤器接受它作为响应。
话虽如此,我应该如何处理数据过滤?
不起作用的东西:
您不能定义 return 闭包的函数或方法,因为闭包类型是匿名的,不能命名。我尝试对结果进行装箱,但它看起来不像 Fn*
特征通过间接方式起作用(可能尚未实现)。
你几乎可以定义一个 filter_by_scope
方法,它接受迭代器本身,过滤它,然后 return 得到结果......除了你不能命名return 类型,因为它将包含闭包类型。
你可以定义一个 ScopeFilter
类型来实现 FnMut(&&isize) -> bool
接口...除非因为特征不稳定,这不是一个好主意(即使它有效现在,肯定 不能与 1.0 一起使用。
您不能将成员 function/method 传递给 filter
,因为它不会部分应用 self
参数。
我能想到的最简单的就是直接调用过滤逻辑方法:
struct Collection {
elements: Vec<isize>,
scope: isize
}
impl Collection {
fn action1(&self) {
for e in self.elements.iter().filter(|e| self.filter(e)) {
println!("got {:?}", e);
}
}
fn filter(&self, cur: &&isize) -> bool {
// Determine if current element needs to be filtered based on the scope value
**cur <= self.scope
}
}
fn main() {
let c = Collection { elements: vec![1, 2, 3, 4, 5, 6, 7, 8], scope: 2 };
c.action1();
}
是的,你必须在你使用它的任何地方写闭包......但它只有六个额外的字符,我唯一能想到的就是宏 ,这会更长。
是的。我认为,在不久的将来,Rust 会相当合理地处理这些问题,而不是现在 .
我想在多个结构方法中调用自定义过滤器,但它应该能够以某种方式访问结构的某个 属性。
这是我目前拥有的一个基本示例:
struct Collection {
elements: Vec<isize>,
scope: isize
}
impl Collection {
fn action1(&self) {
for e in (&self.elements).iter().filter(Collection::filter) {
println!("do something ...");
}
}
fn action2(&self) {
// filter and do something with the elements
}
fn action3(&self) {
// filter and do something with the elements
}
fn filter(cur: &&isize) -> bool {
// Determine if current element needs to be filtered based on the scope value
true
}
}
fn main() {
let c = Collection { elements: vec![1, 2, 3, 4, 5, 6, 7, 8], scope: 2 };
c.action1();
c.action2();
}
我知道我可以直接将闭包/块作为参数传递,但这意味着要跨多个方法复制过滤器逻辑,这是我想避免的。
如果能够做到以下几点就好了:
fn filter(&self, cur: &&isize) -> bool {
}
然而,这不会编译,很可能是因为它实际上是一个方法,而不是一个函数。
如果函数 returns a closure,这也许是可行的,但我无法让过滤器接受它作为响应。
话虽如此,我应该如何处理数据过滤?
不起作用的东西:
您不能定义 return 闭包的函数或方法,因为闭包类型是匿名的,不能命名。我尝试对结果进行装箱,但它看起来不像
Fn*
特征通过间接方式起作用(可能尚未实现)。你几乎可以定义一个
filter_by_scope
方法,它接受迭代器本身,过滤它,然后 return 得到结果......除了你不能命名return 类型,因为它将包含闭包类型。你可以定义一个
ScopeFilter
类型来实现FnMut(&&isize) -> bool
接口...除非因为特征不稳定,这不是一个好主意(即使它有效现在,肯定 不能与 1.0 一起使用。您不能将成员 function/method 传递给
filter
,因为它不会部分应用self
参数。
我能想到的最简单的就是直接调用过滤逻辑方法:
struct Collection {
elements: Vec<isize>,
scope: isize
}
impl Collection {
fn action1(&self) {
for e in self.elements.iter().filter(|e| self.filter(e)) {
println!("got {:?}", e);
}
}
fn filter(&self, cur: &&isize) -> bool {
// Determine if current element needs to be filtered based on the scope value
**cur <= self.scope
}
}
fn main() {
let c = Collection { elements: vec![1, 2, 3, 4, 5, 6, 7, 8], scope: 2 };
c.action1();
}
是的,你必须在你使用它的任何地方写闭包......但它只有六个额外的字符,我唯一能想到的就是宏 ,这会更长。
是的。我认为,在不久的将来,Rust 会相当合理地处理这些问题,而不是现在 .