2016-04-24 5 views
0

私はRustで簡単なことをする方法を理解しようとしていますが、私はborrow checkerと戦ってしまいます。私は単純な関数を書いています。ここではファイル名を渡し、ホームディレクトリにそのファイルへのパスを与えます。このRust機能はどうして仕組みになりませんか?

は、ここでプログラムだ:私はそれを構築しようとすると

use std::env; 

fn filename_in_homedir(filename: &str) -> Option<&str> { 
    let mut homedir = match env::home_dir() { 
     None => return None, 
     Some(p) => p 
    }; 
    homedir.push(filename); 
    homedir.to_str() 
} 

fn main() { 
    match filename_in_homedir(".ssh/id_rsa.pub") { 
     Some(s) => println!("{}", s), 
     None => println!("Oops can't get it") 
    }; 
} 

私はこのエラーを取得する:

$ cargo build 
    Compiling homedir-test v0.1.0 (file:///home/user/code/homedir-test) 
src/main.rs:9:5: 9:12 error: `homedir` does not live long enough 
src/main.rs:9  homedir.to_str() 
        ^~~~~~~ 
src/main.rs:3:56: 10:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 3:55... 
src/main.rs:3 fn filename_in_homedir(filename: &str) -> Option<&str> { 
src/main.rs:4  let mut homedir = match env::home_dir() { 
src/main.rs:5   None => return None, 
src/main.rs:6   Some(p) => p 
src/main.rs:7  }; 
src/main.rs:8  homedir.push(filename); 
       ... 
src/main.rs:7:7: 10:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 7:6 
src/main.rs: 7  }; 
src/main.rs: 8  homedir.push(filename); 
src/main.rs: 9  homedir.to_str() 
src/main.rs:10 } 
error: aborting due to previous error 
Could not compile `homedir-test`. 

動作しない理由を私は理解していません。 env::home_dir()が失敗すると、関数はNoneを返します。成功すると、変数homedirはその値(std::path::PathBuf)を取得します。この時点で、homedir変数はfilename_in_homedirスコープによって所有される必要があります。次の行は、末尾にファイル名を追加するようにhomedirを変更します。これはうまくいきます。最後の行は、.to_str()returnsOption<&str>と呼んでいます。

私は最終的にfilename_in_homedirスコープが終わるかもしれないとき、homedir内のどこかに向いています&strを返すとhomedirてるので、それはこのエラーを投げている理由である、&strがあまりにもないこと、削除されますか?

この機能を正しく機能させるにはどうすればよいですか。何が間違っていますか?

正しいです

答えて

2

Since I'm ultimately returning a &str that's pointing somewhere inside homedir, maybe when the filename_in_homedir scope ends and homedir gets deleted, that &str does too, which is why it's throwing this error?

:あなたはそれを返したら、ポインタを無効、削除されますfilename_in_homedirのスタックフレームによって所有値へのポインタを返すようにしようとしています。 &strではなく、Stringを返す必要があります。これを行うには1つの方法があります:

use std::env; 
use std::borrow::ToOwned; 

fn filename_in_homedir(filename: &str) -> Option<String> { 
    let mut homedir = match env::home_dir() { 
     None => return None, 
     Some(p) => p 
    }; 
    homedir.push(filename); 
    homedir.to_str().map(ToOwned::to_owned) 
} 

fn main() { 
    match filename_in_homedir(".ssh/id_rsa.pub") { 
     Some(s) => println!("{}", s), 
     None => println!("Oops can't get it") 
    }; 
} 
+0

ありがとう、これは素晴らしいです!私は 'std :: borrow'を読むべきだと思うので、頻繁に使う必要があるようです。 – micah

関連する問題