2015-01-17 3 views
2

C 라이브러리 용 Rust 래퍼를 작성하고 싶습니다. Rust의 용어로 C의 라이브러리 원시 포인터 소유권 규칙을 표현해야합니다.메소드의 인수가 자기의 수명보다 긴 수명을 가져야한다고 지정하는 방법은 무엇입니까?

라이브러리의 개인 구조는 다음과 같습니다. struct handle {void *_data} 및 설정자는 set_data(struct handle*, void *data)입니다.

"data은 적어도 handle만큼 오래 있어야합니다."라는 서명이있는 해당 방법의 녹 버전을 만들고 싶습니다.

이 나는 ​​시도했다 :

set_data(&'a self, &'a data:…) 

하지만 검사를 빌려 그 기능, 목적이 아닌 전체 수명에서 수명에 그것을 적용 할 것으로 보인다.

나는 또한 평생을 impl에 추가하려고 시도했지만, 여전히 좋지 않습니다. 전체 테스트 케이스 :

#![allow(unused_variables)] 
struct Handle<'a>; 

impl<'a> Handle<'a> { 
    pub fn set_data(&'a mut self, data: &'a DropCanary) { 
     // save data raw ptr 
    } 

    pub fn use_data(&'a self) { 
     // use data raw ptr 
     println!("alive?"); 
    } 
} 

fn main() { 
    let mut handle = Handle; 
    let long_enough_lifetime = DropCanary{label:"long"}; 

    { 
     let short_lifetime = DropCanary{label:"short"}; 
     handle.set_data(&short_lifetime); // This shouldn't be allowed! 
     handle.set_data(&long_enough_lifetime); // This is OK 
    } 

    handle.use_data(); 
} 

/// --- just for testing --- 

struct DropCanary { 
    label: &'static str, 
} 

impl Drop for DropCanary { 
    fn drop(&mut self) { 
     println!("dropped: {}", self.label); 
    } 
} 

문제는 다음 코드 compiles 출력이 있다는 것입니다 :

떨어 :
짧은 살아?
은 하락 : 녹가 short_lifetimehandle보다 오래해야한다는 것을 모르기 때문에 긴

그래서 그것을 사용-후 무료가 발생합니다.

답변

1

사용자에게 적합합니다 (playpen).

예제가 컴파일되는 이유는 예제 내에서 struct 내부의 수명을 사용하지 않기 때문입니다. 당신이 그것을 사용하지 않기 때문에 그것에 제약이 없으며 단지 생략되었을 수도 있습니다. 당신이 당신의 구조체 안에 평생을 가진 어떤 데이터도 저장하지 않는다면, here을 사용하는 옵션 대신 사용할 수있는 마커 타입이 있습니다.

#![allow(unused_variables)] 
struct Handle<'a>(Option<&'a DropCanary>); 

impl<'a> Handle<'a> { 
    pub fn set_data(&mut self, data: &'a DropCanary) { 
     self.0 = Some(data); 
     // save data raw ptr 
    } 

    pub fn use_data(&self) { 
     // use data raw ptr 
     println!("alive?"); 
    } 
} 

fn main() { 
    let mut handle = Handle(None); 
    let long_enough_lifetime = DropCanary{label:"long"}; 

    { 
     let short_lifetime = DropCanary{label:"short"}; 
     //handle.set_data(&short_lifetime); // This shouldn't be allowed! 
     handle.set_data(&long_enough_lifetime); // This is OK 
    } 

    handle.use_data(); 
} 

/// --- just for testing --- 

struct DropCanary { 
    label: &'static str, 
} 

impl Drop for DropCanary { 
    fn drop(&mut self) { 
     println!("dropped: {}", self.label); 
    } 
} 
+1

고맙습니다! 'ContravariantLifetime' 표시가 필요합니다. – Kornel

+1

지금 PhantomData라고합니다. – Kornel

+0

마커를 포함하지 않으면 오류가 발생합니다. –