我正在玩Nickel.rs来构建一个待办事项列表示例。由于暂时不支持闭包,我试图找到另一种处理我实现的简单结构的方法。
这是我的代码:
extern crate nickel;
use std::io::net::ip::Ipv4Addr;
use nickel::{Nickel, Request, Response};
struct TaskList {
list: Vec<String>
}
impl TaskList {
fn new() -> TaskList {
TaskList { list: Vec::new() }
}
fn add_task (&mut self, task: &str) {
&self.list.push(task.to_string());
}
fn get_tasks (&self) -> Vec<String> {
self.list.to_vec()
}
}
fn main() {
let mut server = Nickel::new();
static mut sample : TaskList = TaskList { list: Vec::new() };
sample.add_task("First");
sample.add_task("Second");
fn fetch_tasks (_request: &Request, response: &mut Response) {
response.send(sample.get_tasks().to_string())
}
server.utilize(Nickel::static_files("./public"));
server.get("/task", fetch_tasks);
server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
}
但编译器给我写了这样的话:“不允许有可变的静态项目具有析构函数”
您对我如何解决这个问题有什么建议吗?
答案 0 :(得分:0)
我不确定你想要实现的目标。
如果希望TaskList存在于堆上,请使用Box。但是,堆栈范围应该是server.listen()中的有效事件,所以我不明白为什么你需要TaskList成为静态mut?
如果你想搞乱静态变量,你必须做得不安全,如下所示:
use std::mem::transmute;
use std::ptr;
struct Static {
v: int
}
impl Static {
fn whatever(&mut self) {
println!("Write to static");
self.v += 1;
}
}
static mut _data:*const Static = 0 as *const Static;
unsafe fn get<'a>() -> &'a mut Static {
if _data == ptr::null::<Static>() {
// Notice this is a Box<Static>, which is a *Static allocated on the heap
// transmute(Static { v: 0 }) wouldn't work because once the stack scope ends
// the instance would no longer be valid; Box<T> lasts beyond the call to get()
_data = transmute(box Static { v: 0 });
}
return transmute(_data);
}
unsafe fn release() {
ptr::read::<Static>(_data);
}
impl Drop for Static {
fn drop(&mut self) {
println!("Dropped static");
}
}
fn main() {
unsafe {
let foo = get();
foo.whatever();
}
unsafe {
let foo = get();
foo.whatever();
}
unsafe {
release();
}
println!("Done");
}
我真的强烈建议不要这样做,除非有一个很好的理由。
大多数情况下,您可以假设您在一个范围内创建的变量:
{
let foo = Bar;
...
} <-- End
在该范围结束前将继续有效。
像server.get这样的子调用仍在main(){}范围内,其中定义了sample。
它仍然有效。