我试图简化闭包,但是当参数属于闭包但内部函数调用只需要一个引用时,我在将闭包转换为关联函数的引用时遇到了问题。
#![deny(clippy::pedantic)]
fn main() {
let borrowed_structs = vec![BorrowedStruct, BorrowedStruct];
//Selected into_iter specifically to reproduce the minimal scenario that closure gets value instead of reference
borrowed_structs
.into_iter()
.for_each(|consumed_struct: BorrowedStruct| MyStruct::my_method(&consumed_struct));
// I want to write it with static method reference like following line:
// for_each(MyStruct::my_method);
}
struct MyStruct;
struct BorrowedStruct;
impl MyStruct {
fn my_method(prm: &BorrowedStruct) {
prm.say_hello();
}
}
impl BorrowedStruct {
fn say_hello(&self) {
println!("hello");
}
}是否可以简化此代码:
into_iter().for_each(|consumed_struct: BorrowedStruct| MyStruct::my_method(&consumed_struct));以下各点:
into_iter().for_each(MyStruct::my_method)请注意,这里的into_iter只是为了重现我在闭包中拥有的值的场景。我知道在这种场景中可以使用iter,但这不是我正在处理的真实场景。
发布于 2019-04-12 13:52:51
我不认为有一个for_each_ref在特质Iterator。但是您可以很容易地编写自己的(游乐场)
trait MyIterator {
fn for_each_ref<F>(self, mut f: F)
where
Self: Iterator + Sized,
F: FnMut(&Self::Item),
{
self.for_each(|x| f(&x));
}
}
impl<I: Iterator> MyIterator for I {}borrowed_structs
.into_iter()
.for_each_ref(MyStruct::my_method);另一个选项是,如果您能够更改my_method函数的原型,您可以让它通过值或引用来接受该值:
impl MyStruct {
fn my_method(prm: impl Borrow<BorrowedStruct>) {
let prm = prm.borrow();
prm.say_hello();
}
}然后,您使用.for_each(MyStruct::my_method)的原始代码就可以工作了。
第三种选择是使用泛型包装函数(游乐场)。
fn bind_by_ref<T>(mut f: impl FnMut(&T)) -> impl FnMut(T) {
move |x| f(&x)
}然后使用.for_each(bind_by_ref(MyStruct::my_method));调用包装函数。
https://stackoverflow.com/questions/55652824
复制相似问题