将struct字段初始化为临时目录并从目录中读取

时间:2015-03-18 11:27:07

标签: file io rust tempdir

我正在尝试使用一个结构,该结构具有一个我认为应该是Result<TempDir>类型的字段。当我使用new()初始化字段的实现时,我希望通过创建新的临时目录来初始化该特定字段。后来,我想实现一个从该目录中读取的方法。

这里是代码,我更担心库的语法和正确使用(为什么在Rust中存在超过四个用于读/写缓冲的库,这是疯了)因为逻辑应该是正确的。不要太担心特质实现,我只需要语法中的方向。请不要过于苛刻,因为我知道它不会编译,但只需要进行两次更改。

    extern crate rustc_back;
    use std::path::Path;
    use std::fs::File;
    use rustc_back::tempdir::TempDir as TempDir;
    pub struct MyStorage {

      temp_dir : Result<TempDir>
    }

    impl MyStorage {
      pub fn new() -> MyStorage { 
        //tempo = match TempDir::new("encrypt_storage");
        let store = match TempDir::new("encrypt_storage") {
          Ok(dir) => dir,
            Err(e) => panic!("couldn't create temporary directory: {}", e)
        };

        MyStorage { temp_dir: store }
        //MyStorage { temp_dir: TempDir::new("encrypt_storage") }
      }
    }

    impl Storage for MyStorage {
      fn get(&self, name: Vec<u8>) -> Vec<u8> {
    //let mut f = std::fs::File::open(self.temp_dir.path() / name);
    let mut f = std::fs::File::open(&self.temp_dir){
        // The `desc` field of `IoError` is a string that describes the error
        Err(why) => panic!("couldn't open: {}", why.description()),
        Ok(file) => file,
    };
    let mut s = String::new();
    //f.read_to_string(&mut s);
    match f.read_to_string(&mut s){
        Err(why) => panic!("couldn't read: {}", why.description()),
        Ok(_) => print!("contains:\n{}", s),
    }
    s.to_vec()
  }

  fn put(&mut self, name: Vec<u8>, data: Vec<u8>) {
    // self.entries.push(Entry { name : name, data : data })
    let mut f = File::create(self.temp_dir.path() / name);
    f.write_all(data);
  }

      fn put(&mut self, name: Vec<u8>, data: Vec<u8>) {
        // self.entries.push(Entry { name : name, data : data })
        let mut f = File::create(self.temp_dir.path() / name);
        f.write_all(data);
      }
    }

1 个答案:

答案 0 :(得分:1)

修复缩进后(Rust每个级别使用4个空格),删除Storage for,因为您没有提供该特征,删除已注释掉的代码,并添加main,留下这个:

extern crate rustc_back;
use std::path::Path;
use std::fs::File;
use rustc_back::tempdir::TempDir as TempDir;

pub struct MyStorage {
    temp_dir : Result<TempDir>
}

impl MyStorage {
    pub fn new() -> MyStorage { 
        let store = match TempDir::new("encrypt_storage") {
            Ok(dir) => dir,
            Err(e) => panic!("couldn't create temporary directory: {}", e)
        };

        MyStorage { temp_dir: store }
    }
}

impl MyStorage {
    fn get(&self, name: Vec<u8>) -> Vec<u8> {
        let mut f = std::fs::File::open(self.temp_dir.path() / name);
        let mut s = String::new();
        f.read_to_string(&mut s);
        s.to_vec()
     }

    fn put(&mut self, name: Vec<u8>, data: Vec<u8>) {
        let mut f = File::create(self.temp_dir.path() / name);
        f.write_all(data);
    }
}

fn main() {}

编译出现此错误:

error: wrong number of type arguments: expected 2, found 1 [E0243]
temp_dir : Result<TempDir>
           ^~~~~~~~~~~~~~~

很好地指出了有问题的类型。让我们看看the docs for Result,其中包括定义:

pub enum Result<T, E> {
    Ok(T),
    Err(E),
} 

因此Result有两个类型参数 - T用于成功案例,E用于失败案例。您的代码只指定其中一个。我的猜测是你看了docs for TempDir并复制并粘贴了:

fn new(prefix: &str) -> Result<TempDir>

但是,如果您点击那里的Result,则会看到它转到io::Result,这只是将E绑定到{{3}的类型别名}:

type Result<T> = Result<T, Error>; 

通过所有展示,您可以“修复”#34;通过更改MyStorage结构:

来解决您的问题
pub struct MyStorage {
    temp_dir: std::io::Result<TempDir>,
}

然后你会得到另一个编译器错误,因为你已经通过Result中的match处理了MyStorage::new 。您没有存储io::Result<TempDir>,而只是存储TempDir!进一步改变你的结构:

pub struct MyStorage {
    temp_dir: TempDir,
}

解锁一整套新的错误让你弄明白;但现在你已经超越了第一道障碍了!