2015-03-23 2 views
3

Я пытаюсь получить следующий код работает в сценарии сборки:PathBuf не живут достаточно долго

use std::path::PathBuf; 
use std::env; 
use std::ffi::AsOsStr; 

fn main() { 
    let mut string = env::var("CARGO_MANIFEST_DIR").unwrap(); 
    let mut main_dir = PathBuf::new(string); 
    main_dir.push("src/dependencies"); 

    let test_str = main_dir.as_os_str(); // test_str gets the same lifetime as main_dir 

    let second_test = test_str.to_str(); 

    let last_test = second_test.unwrap(); 
    panic!(&last_test); 
} 

я получаю следующие ошибки:

<anon>:10:24: 10:32 error: `main_dir` does not live long enough 
<anon>:10   let test_str = main_dir.as_os_str(); // test_str gets the same lifetime as main_dir 
           ^~~~~~~~ 
note: reference must be valid for the static lifetime... 
<anon>:7:48: 16:6 note: ...but borrowed value is only valid for the block suffix following statement 1 at 7:47 
<anon>:7   let mut main_dir = PathBuf::new(string); 
<anon>:8   main_dir.push("src/dependencies"); 
<anon>:9  
<anon>:10   let test_str = main_dir.as_os_str(); // test_str gets the same lifetime as main_dir 
<anon>:11  
<anon>:12   let second_test = test_str.to_str(); 
      ... 
<anon>:15:17: 15:26 error: `last_test` does not live long enough 
<anon>:15   panic!(&last_test); 
          ^~~~~~~~~ 
<std macros>:1:1: 12:62 note: in expansion of panic! 
<anon>:15:9: 15:28 note: expansion site 
note: reference must be valid for the static lifetime... 
<anon>:14:45: 16:6 note: ...but borrowed value is only valid for the block suffix following statement 5 at 14:44 
<anon>:14   let last_test = second_test.unwrap(); 
<anon>:15   panic!(&last_test); 
<anon>:16  } 
error: aborting due to 2 previous errors 

Я буквально экономить каждый значение в собственной переменной. Итак, как это невозможно не пережить заявление? Я знаю, что есть и «in_os_string», но почему мой подход не работает?

Я действительно пытаюсь понять всю жизнь, но это очень сложно. Может быть, кто-то может быстро пройти мой пример и рассказать мне, что происходит со сроками жизни в каждом заявлении и почему он не работает? Это мне очень помогло.

+0

Извините за что, просто обновил код для работы на манеже;) – Reignbeaux

ответ

4

Комментируя строки кода, мы можем обнаружить, что это строка panic!, которая терпит неудачу. Первый аргумент panic! должен быть строкой форматирования, которая должна иметь продолжительность жизни 'static, поскольку она фактически скомпилирована.

Небольшой пример, который повторяет это:

let s = "Foo".to_string(); 
panic!(&s); 

Но по какой-то причине, этот пример имеет сообщение об ошибке много лучше, тот, который указывает на &s.

Для примера, вы можете просто изменить panic! линию:

panic!("{}", last_test); 
+0

Хорошо, что было almose слишком легко: DI была слишком неподвижной на всю жизнь, что я этого не осознавал. Еще раз спасибо – Reignbeaux

+0

Не беспокойтесь; действительно плохое сообщение об ошибке удивительно. Я пытаюсь понять, могу ли я понять, почему здесь так плохо. – Shepmaster

+0

Я [создал ошибку] ​​(https://github.com/rust-lang/rust/issues/23685) - мы увидим, есть ли возможное сообщение об ошибке. – Shepmaster

Смежные вопросы