2015-09-07 2 views
2

Этот код выглядит, как он будет работать нормально для меня, но ржавчина заимствуют шашка не нравится:Борьба с Rust заема проверки

extern crate rustbox; 

use std::error::Error; 
use std::default::Default; 

use rustbox::{Color, RustBox}; 
use rustbox::Key; 

use std::fs::File; 
use std::env; 
use std::io::BufReader; 
use std::io::BufRead; 

fn display_screenful(rb: &RustBox, fr: BufReader<&'static File>, offset: usize) { 
    for (rline, idx) in fr.lines().zip(0..).skip(offset).take(rb.height()) { 
     match rline { 
      Ok(line) => (*rb).print(0, idx, rustbox::RB_NORMAL, Color::White, Color::Black, &line), 
      Err(_) => (*rb).print(0, idx, rustbox::RB_NORMAL, Color::White, Color::Black, "") 
     } 
    } 
} 

fn main() { 
    let rustbox = match RustBox::init(Default::default()) { 
     Ok(v) => v, 
     Err(e) => panic!(e), 
    }; 

    let path = env::args().nth(1).unwrap(); 
    let file = match File::open(&path) { 
     Ok(file) => file, 
     Err(e) => panic!(e) 
    }; 
    let file_reader = BufReader::new(&file); 

    display_screenful(&rustbox, file_reader, 0); 
    rustbox.present(); 

    loop { 
     match rustbox.poll_event(false) { 
      Ok(rustbox::Event::KeyEvent(key)) => { 
       match key { 
        Some(Key::Char('q')) => { break; } 
        Some(Key::Char(' ')) => { 
         display_screenful(&rustbox, file_reader, rustbox.height()); 
         rustbox.present(); 
        } 
        _ => { } 
       } 
      }, 
      Err(e) => panic!("{}", e.description()), 
      _ => { } 
     } 
    } 
} 

Я предполагаю, что я не мог использовать отдельную функцию, а также использование вместо этого, для частей цикла, но это не идиоматическая Rust, и это не хорошая практика кодирования. На самом деле, я пробовал это, но он просто говорит мне, что я использую перемещенное значение. Вот некоторые ошибки, которые я получаю:

Compiling rusted v0.1.0 (file:///Users/christopherdumas/rusted) 
src/main.rs:34:39: 34:43 error: `file` does not live long enough 
src/main.rs:34  let file_reader = BufReader::new(&file); 
                ^~~~ 
note: reference must be valid for the static lifetime... 
src/main.rs:33:7: 55:2 note: ...but borrowed value is only valid for the block suffix following statement 2 at 33:6 
src/main.rs:33  }; 
src/main.rs:34  let file_reader = BufReader::new(&file); 
src/main.rs:35 
src/main.rs:36  display_screenful(&rustbox, file_reader, 0); 
src/main.rs:37  rustbox.present(); 
src/main.rs:38 
       ... 
src/main.rs:45:53: 45:64 error: use of moved value: `file_reader` [E0382] 
src/main.rs:45       display_screenful(&rustbox, file_reader, rustbox.height()); 
                    ^~~~~~~~~~~ 
src/main.rs:45:53: 45:64 help: run `rustc --explain E0382` to see a detailed explanation 
src/main.rs:36:33: 36:44 note: `file_reader` moved here because it has type `std::io::buffered::BufReader<&'static std::fs::File>`, which is non-copyable 
src/main.rs:36  display_screenful(&rustbox, file_reader, 0); 
               ^~~~~~~~~~~ 
error: aborting due to 2 previous errors 
Could not compile `rusted`. 

To learn more, run the command again with --verbose. 
+1

Я не могу проверить это на данный момент, но я думаю, что проблема заключается в статике в 'BufReader <& 'static File>'. Вы просите компилятор гарантировать, что ссылка будет действительна для срока службы программы, что в данном случае неверно, поэтому компилятор сообщает вам, что ваш файловый объект не проживает достаточно долго. –

ответ

4

Во-первых, вы не должны просить BufReader<&'static File>. Вы не можете его предоставить. Задайте вместо этого BufReader<&'a File> на некоторое время жизни 'a.

fn display_screenful<'a>(rb: &RustBox, fr: BufReader<&'a File>, offset: usize) 

или, для краткости,

fn display_screenful(rb: &RustBox, fr: BufReader<&File>, offset: usize) 

Этого не достаточно либо - вы тогда в конечном итоге перемещение file_reader в функцию. Вместо этого вы должны взять взаймы:

fn display_screenful(rb: &RustBox, fr: &mut BufReader<&File>, offset: usize) 

а затем он компилируется.