2016-07-02 2 views
0

이 작동 :오류 : xxx는 살지 않는이 충분히

fn user_add<'x>(data: &'x Input, db: &'x mut Database<'x>) -> HandlerOutput { 
    //let input: UserAddIn = json::decode(&data.post).unwrap(); 
    //let username = input.username.as_bytes(); 
    //let password = input.password.as_bytes(); 
    db.put(b"Hi", b"hello"); 
    //db.delete(username); 
    Ok("Hi".to_string()) 
} 

이 작동하지 않습니다

fn user_add<'x>(data: &'x Input, db: &'x mut Database<'x>) -> HandlerOutput { 
    //let input: UserAddIn = json::decode(&data.post).unwrap(); 
    //let username = input.username.as_bytes(); 
    //let password = input.password.as_bytes(); 
    let my_str = "hi".to_string(); 
    let username = my_str.as_bytes(); 
    db.put(username, b"hello"); 
    //db.delete(username); 
    Ok("Hi".to_string()) 
} 

컴파일러 출력 : I에 대한 몇 가지 질문을 본 적이

src/handlers.rs:85:17: 85:23 error: `my_str` does not live long enough 
src/handlers.rs:85  let username = my_str.as_bytes(); 
             ^~~~~~ 
src/handlers.rs:80:77: 89:2 note: reference must be valid for the lifetime 'x as defined on the block at 80:76... 
src/handlers.rs:80 fn user_add<'x>(data: &'x Input, db: &'x mut Database<'x>) -> HandlerOutput { 
src/handlers.rs:81  //let input: UserAddIn = json::decode(&data.post).unwrap(); 
src/handlers.rs:82  //let username = input.username.as_bytes(); 
src/handlers.rs:83  //let password = input.password.as_bytes(); 
src/handlers.rs:84  let my_str = "hi".to_string(); 
src/handlers.rs:85  let username = my_str.as_bytes(); 
        ... 
src/handlers.rs:84:32: 89:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 84:31 
src/handlers.rs:84  let my_str = "hi".to_string(); 
src/handlers.rs:85  let username = my_str.as_bytes(); 
src/handlers.rs:86  db.put(username, b"hello"); 
src/handlers.rs:87  //db.delete(username); 
src/handlers.rs:88  Ok("Hi".to_string()) 
src/handlers.rs:89 } 

을 평생 녹에 내 생각 엔 그 책이 이 아니고 그 책이 인 것 같아요. 나는 아직도 일생을 시행 착오로 사용한다. 컴파일러와의 싸움을 여러 번 시도했기 때문에이 특별한 경우는 혼란 스러웠습니다. 녹 기술이 있으면 책의 수명에 관한 부분을 편집 해보십시오.

답변

3

첫 번째 경우 b"Hi"은 바이트 리터럴이고 "u8 무한한 수명의 슬라이스"를 의미하는 &'static [u8] 유형을가집니다. 기능 put은 평생 'x이 필요합니다. 'static은 평생보다 더 오래 살기 때문에 녹을 사용하면 행복합니다. 두 번째 경우

let my_str = "hi".to_string(); 
let username = my_str.as_bytes(); 

username에서

my_str의 내부 버퍼에 대한 참조이며보다 길게 지속 할 수 없다. put의 첫 번째 인수의 수명이 'x이어야하며 my_str (로컬에서 user_add)보다 넓어야하므로 컴파일러에서 불만을 표시합니다. 녹 당신이 할 수 없습니다 db 함수 호출의 끝에서 데이터를 매달려를 가리키는 것이기 때문에 그 :

user_add(input, &mut db); 
// `my_str` was local to `user_add` and doesn't exist anymore 
// if Rust had allowed you to put it in `db`, `db` would now contain some invalid data here 
1

덕분에 오류가 발생하는 이유는 응답에 대한 @mcarton 할 수 있습니다. 이 대답에서 나는 그것을 해결하는 방법을 분명히 becames도 희망한다.


컴파일러의 코드 생성은 완벽하지만 오류 메시지가 나에게 단지 몹시 혼란 입니다.

문제점은 내가 작성한 다른 라이브러리에서 발생한 것이므로 데이터베이스입니다. 데이터베이스 구조체에는 조각을 보유하는 항목이 들어 있습니다. 그것은 슬라이스가 보유하고있는 데이터가 데이터베이스 구조체보다 더 오래 살기를해야한다는 것을 의미

struct Entry<'a> { 
    key: &'a [u8], 
    value: &'a [u8], 
} 

pub struct Database<'a> { 
    file: File, 
    entries: Vec<Entry<'a>>, 
} 

:로 조각의 수명은 설정되었다. username 변수는 범위를 벗어나지 만 참조가 포함 된 데이터베이스는 여전히 존재합니다. 즉, 데이터베이스는 정적 변수와 같이 수명보다 긴 데이터를 보유해야 데이터베이스가 쓸모 없게됩니다.

라이브러리가 정상적으로 컴파일되었습니다. 그러나 그 오류는 다른 곳에서 나타났다.

벡터가 포인터가 아니기 때문에 그 해결책은 벡터 조각을 교환하는 것이 었습니다. 벡터는 데이터베이스보다 작을 수 있습니다.

struct Entry { 
    key: Vec<u8>, 
    value: Vec<u8>, 
} 

pub struct Database { 
    file: File, 
    entries: Vec<Entry>, 
}