Rust中的方法数组

问题描述 投票:0回答:1

我正在尝试在Rust中编写一个请求“路由器”:与匹配发生时要调用的函数关联的表达式列表。函数可能是来自各种对象的方法,这当然会使借阅检查器抱怨。这是我想要的示例:

use std::collections::HashMap;

struct Foo(bool);

impl Foo {
    fn say(&self) {
        println!("I'm {}", self.0);
    }
    fn morph(&mut self) {
        self.0 = !self.0;
    }
}

fn main() {
    let mut foo = Foo(true);

    let mut routes: HashMap<String, Box<FnMut()>> = HashMap::new();
    routes.insert("foo/say".to_string(), Box::new(|| foo.say()));  //< First (immutable) borrow of foo
    routes.insert("foo/morph".to_string(), Box::new(|| foo.morph())); //< Second (mutable) borrow of foo
    routes.insert("bar".to_string(), Box::new(|| println!("hello"))); //< Compiler also says immutable foo is used here
}

我理解为什么借用检查器对此不满意,但是我想知道在Rust中实现该功能的惯用方式是什么

旁注:对获取异构函数列表/数组/哈希图的最佳方法的任何一般性评论,将不胜感激。

rust borrow-checker borrowing
1个回答
0
投票

解决方案非常简单,真的。因为您将需要一个允许您按需获得可变借入的结构,所以需要RwLock。而且因为我猜您正在构建的是HTTP路由器,所以要绕过Foo上的生存期要求,您将需要将RwLock包装在Arc中,如下所示:

use std::collections::HashMap;
use std::sync::{Arc, RwLock};

struct Foo(bool);

impl Foo {
    fn say(&self) {
        println!("I'm {}", self.0);
    }
    fn morph(&mut self) {
        self.0 = !self.0;
    }
}

fn main() {
    let mut foo = Arc::new(RwLock::new(Foo(true)));

    let mut routes: HashMap<String, Box<FnMut()>> = HashMap::new();
    routes.insert("foo/say".to_string(), Box::new(|| foo.read().unwrap().say()));  //< First (immutable) borrow of foo
    routes.insert("foo/morph".to_string(), Box::new(|| foo.write().unwrap().morph())); //< Second (mutable) borrow of foo
    routes.insert("bar".to_string(), Box::new(|| println!("hello"))); //< Compiler also says immutable foo is used here
}

请注意,我滥用了这样一个事实,即所有内容都只能为此借用foo只读。如果您需要在闭包中添加move内容,则Arc实现Clone,因此您绝对应该利用此优势。

其余的很好-只要您所有的闭包都具有相同的签名,将它们装箱并将它们存储在任何集合中都是习惯性的。

© www.soinside.com 2019 - 2024. All rights reserved.