2017-01-23 5 views
2

私は現在の実行可能ファイル名を取得するだけで簡単です(そして、危険にも注意してください)。私はそれを動作させましたが、私の関数は&strStringに変換し、後でパターンマッチングのためにas_str()を呼び出します。PathBufを文字列に変換するときにクローンを避ける方法はありますか?

fn binary_name() -> String { 
    std::env::current_exe().unwrap().file_name().unwrap().to_str().unwrap().to_string() 
} 

私の理解では、std::env::current_exe()は私がそれを返すことで転送することができPathBufの所有権を与えます。それがそのままで、私はそれを&strに変換するために借ります。そこから、文字列を返す唯一の方法は、PathBufが削除される前にそれを複製することです。

これを避ける方法はありますか?&OsStr -> &str -> String -> &strサイクルですか?

答えて

3

PathBufStringに変換するときにクローニングを回避する方法はありますか?

絶対に。しかし、それはあなたがやっていることではありません。 PathBuffile_nameに変換して変換しています。文字列の一部の所有権を取得することはできません。

サブセットを使用していなかった場合は、に変換してからStringに変換すると、サブセットを使用していない場合は、PathBuf全体を変換することができます。ここで、私は特定のエラーを無視して、成功または失敗を返す:

use std::path::PathBuf; 

fn exe_name() -> Option<String> { 
    std::env::current_exe() 
     .ok() 
     .map(PathBuf::into_os_string) 
     .and_then(|exe| exe.into_string().ok()) 
} 

はこの&OsStr -> &str -> String -> &strサイクルを回避するための方法はありますか?

いいえ、あなたはあなたのメソッド内(コードの変形に応じて、所有権を保持している方、またはOsStringまたはPathBufStringを作成しているので。 Return local String as a slice (&str)を参照して、スタック割り当てアイテム(文字列を含む)への参照を返せない理由を確認してください。あなたが参照しているしたい場合は、そのQ & Aで述べたように

は、データを所有している事が参照をより長生きするために持っている:あなたの元のコードは上のクラッシュしないように記述することができ


use std::env; 
use std::path::Path; 
use std::ffi::OsStr; 

fn binary_name(path: &Path) -> Option<&str> { 
    path.file_name().and_then(OsStr::to_str) 
} 

fn main() { 
    let exe = env::current_exe().ok(); 
    match exe.as_ref().and_then(|e| binary_name(e)) { 
     Some("cat") => println!("Called as cat"), 
     Some("dog") => println!("Called as dog"), 
     Some(other) => println!("Why did you call me {}?", other), 
     None => println!("Not able to figure out what I was called as"), 
    } 
} 
簡単にエラーが発生する

fn binary_name() -> Option<String> { 
    let exe = std::env::current_exe(); 
    exe.ok() 
     .as_ref() 
     .and_then(|p| p.file_name()) 
     .and_then(|s| s.to_str()) 
     .map(String::from) 
} 
+0

Neat。私は機能の外で所有権を移さずに方法がないと思った。ちょうど私のCの方法が輝いている。 – mgoszcz2

+0

@ mgoszcz2私があなたに従っているかどうかはわかりません。第1および第3の例では、新しいデータが割り当てられ、第2の例では、所有権*は関数外です。 – Shepmaster

+0

いいえ、それはちょうどCです。私は 'argv [0] + offset'へのポインタを返します。 – mgoszcz2

関連する問題