首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接受引用的函数能否作为闭包参数传递,从而提供所拥有的值?

接受引用的函数能否作为闭包参数传递,从而提供所拥有的值?
EN

Stack Overflow用户
提问于 2019-04-12 13:31:48
回答 1查看 64关注 0票数 1

我试图简化闭包,但是当参数属于闭包但内部函数调用只需要一个引用时,我在将闭包转换为关联函数的引用时遇到了问题。

代码语言:javascript
复制
#![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");
    }
}

游乐场

是否可以简化此代码:

代码语言:javascript
复制
into_iter().for_each(|consumed_struct: BorrowedStruct| MyStruct::my_method(&consumed_struct));

以下各点:

代码语言:javascript
复制
into_iter().for_each(MyStruct::my_method)

请注意,这里的into_iter只是为了重现我在闭包中拥有的值的场景。我知道在这种场景中可以使用iter,但这不是我正在处理的真实场景。

EN

回答 1

Stack Overflow用户

发布于 2019-04-12 13:52:51

我不认为有一个for_each_ref在特质Iterator。但是您可以很容易地编写自己的(游乐场)

代码语言:javascript
复制
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 {}
代码语言:javascript
复制
borrowed_structs
    .into_iter()
    .for_each_ref(MyStruct::my_method);

另一个选项是,如果您能够更改my_method函数的原型,您可以让它通过值或引用来接受该值:

代码语言:javascript
复制
impl MyStruct {
    fn my_method(prm: impl Borrow<BorrowedStruct>) {
        let prm = prm.borrow();
        prm.say_hello();
    }
}

然后,您使用.for_each(MyStruct::my_method)的原始代码就可以工作了。

第三种选择是使用泛型包装函数(游乐场)

代码语言:javascript
复制
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));调用包装函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55652824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档