rust - 静态可变数据的惯用替代方法是什么?

标签 rust iron

我正在使用 Iron 框架创建一个简单的端点。我有端点需要访问的有状态、可变数据。

这里有一些代码表明了我的意图:

extern crate iron;
extern crate mount;

use iron::{Iron, Request, Response, IronResult};
use iron::status;
use mount::Mount;

static mut s_counter: Option<Counter> = None;

struct Counter {
    pub count: u8
}

impl Counter {
    pub fn new() -> Counter {
        Counter {
            count: 0
        }
    }

    pub fn inc(&mut self) {
        self.count += 1;
    }
}

fn main() {
    unsafe { s_counter = Some(Counter::new()); }
    let mut mount = Mount::new();
    mount.mount("/api/inc", inc);
    println!("Server running on http://localhost:3000");
    Iron::new(mount).http("127.0.0.1:3000").unwrap();
}

fn inc(req: &mut Request) -> IronResult<Response> {
    let mut counter: Counter;
    unsafe {
        counter = match s_counter {
            Some(counter) => counter,
            None => { panic!("counter not initialized"); }
        };
    }
    counter.inc();
    let resp = format!("{}", counter.count);
    Ok(Response::with((status::Ok, resp)))
}

此代码无法编译:

error: cannot move out of static item

我希望有更好的方法来做到这一点,不涉及任何不安全的代码或static mut。我的问题是,实现这一目标的惯用方法是什么?

最佳答案

我强烈建议您完整阅读 The Rust Programming Language ,尤其是 chapter on concurrency . Rust 社区付出了很多努力来制作高质量的文档来帮助人们摆脱困境。

在这种情况下,我可能只是让 Counter 构造一个 Iron Handler .然后,我会在结构中使用一个原子变量来保存计数而不需要可变性:

extern crate iron;
extern crate mount;

use std::sync::atomic::{AtomicUsize, Ordering};

use iron::{Iron, Request, Response, IronResult};
use iron::status;
use mount::Mount;

struct Counter {
    count: AtomicUsize,
}

impl Counter {
    pub fn new() -> Counter {
        Counter {
            count: AtomicUsize::new(0),
        }
    }
}

fn main() {
    let mut mount = Mount::new();
    mount.mount("/api/inc", Counter::new());
    println!("Server running on http://localhost:3000");
    Iron::new(mount).http("127.0.0.1:3000").unwrap();
}

impl iron::Handler for Counter {
    fn handle(&self, _: &mut Request) -> IronResult<Response> {
        let old_count = self.count.fetch_add(1, Ordering::SeqCst);

        let resp = format!("{}", old_count);

        Ok(Response::with((status::Ok, resp)))
    }
}

关于rust - 静态可变数据的惯用替代方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32685853/

相关文章:

rust - 如何在 Linux 上从命令行访问 API 文档?

arrays - 如何在 Rust 0.7 中迭代字符串数组

rust - 如何在 Iron 中生成指向特定路线的链接?

rust - 如何在 Iron 中查找当前 URL?

rust - 如何将结构更新语法与不可变借用一起使用?

rust - 了解相关的生命周期

iron - 哪里可以下载 Iron Javascript

rust - 宏是否可以采用常量表达式和 "inline"来生成有效的 LiteralPattern?

svg - 自定义图标未显示在铁图标中