2014-09-21 4 views
1

나는 todo 목록 예제를 만들기 위해 Nickel.rs와 놀고있다. 클로저는 현재 지원되지 않으므로 구현 된 간단한 구조를 다른 방법으로 처리하려고합니다.Rust의 정적 구조체

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

나는 당신이 성취하려는 것을 정말로 모르겠습니다.

TaskList를 힙에 존재 시키려면 Box를 사용하십시오. 그러나 stack scope는 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과 같은 서브 호출은 여전히 ​​sample이 정의 된 main() {} 범위 내에 있습니다.

그래도 유효합니다.

+0

필자는 'sample'변수를 정적으로 만들지 않고 main() {}에서 정의했기 때문에 'fetch_tasks'함수에서 액세스 할 수 있다고 가정했습니다. 하지만 컴파일러는 'fetch_task'에서 동적 인 환경을 포착 할 수 없다고 말하면서 클로저를 사용해야합니다. 하지만 router.get()에는 두 번째 매개 변수에 대한 함수가 필요합니다. –

+0

@ThomasC__'Request' 문맥이 주어지면'TaskList' 핸들을 접근 할 수 있도록 "미들웨어"를 사용해야 할 것입니다. 미들웨어의 몇 가지 예를 확인해보십시오. – BurntSushi5