2016-07-02 15 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()) 
} 

コンパイラ出力:私はについていくつかの質問を見てきました

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"はバイトリテラルで、タイプが&'static [u8]であることを意味します。これは、「スライスがu8で無限の寿命を持つ」ことを意味します。機能putは生涯が'xである必要があります。'staticの生存時間はどの生涯よりも長いため、Rustはそれを使用してうれしく思います。第2のケースで

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

usernamemy_strの内部バッファへの参照であり、それよりも長生きすることができません。 putの最初の引数の有効期間は'xで、my_str(ローカルの場合はuser_add)より広いため、コンパイラは不平を言います。 dbは、関数呼び出しの終わりにデータをダングリングするポイントになるので錆は、あなたがそれを行うことを許可しません:エラーが発生した理由を答えるため@mcartonする

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

感謝を。この回答で私はそれも解決する方法を明確に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>, 
} 
関連する問題