从文件中读取时输入演绎错误

时间:2017-05-09 19:46:25

标签: file-io rust

根据multiple sources,我认为这是从文件中读取字符串的正确方法:

use std::error::Error;

fn main() {
    let path = std::path::Path::new("input.txt");

    let file = match std::fs::File::open(&path) {
        Err(e) => {
            panic!("Failed to read file {}: {}",
                   path.display(),
                   e.description())
        }
    };

    let mut s = String::new();
    let mut v = Vec::new();
    match file.read_to_string(&mut s) {
        Err(e) => panic!("Failed to read file contents: {}", e.description()),
    }

    println!("{}", s);
}

但是这段代码使用Rust 1.17.0会产生错误,所以我必须遗漏一些东西:

error: the type of this value must be known in this context
  --> src/main.rs:16:11
   |
16 |     match file.read_to_string(&mut s) {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^

1 个答案:

答案 0 :(得分:4)

您有多个重叠问题。每当调试编程问题时,创建Minimal, Complete Verifiable Example

都会有所帮助

首先评论match file.read_to_string(&mut s) { /* ... */ }。然后你会得到另一个错误:

error[E0282]: type annotations needed
  --> src/main.rs:15:17
   |
15 |     let mut v = Vec::new();
   |         -----   ^^^^^^^^ cannot infer type for `T`
   |         |
   |         consider giving `v` a type

注释掉那一行,给出:

error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
 --> src/main.rs:6:22
  |
6 |     let file = match std::fs::File::open(&path) {
  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered

这是你真正的问题。 Result是包含两个值OkErr的枚举。您必须处理匹配中的所有变体。

在这种情况下,最简单的方法是使用unwrap_or_else

let file = std::fs::File::open("input.txt").unwrap_or_else(|e| {
    panic!(
        "Failed to read file {}: {}",
        path.display(),
        e.description()
    )
});

您可以删除未使用的向量,并将相同的unwrap_or_else应用于其他失败案例。然后你需要:

  1. 导入std::io::Read
  2. file声明为可变。
  3. 你也可以:

    1. 使用{}直接打印错误。
    2. 将字符串切片传递给File::open
    3. use std::io::Read;
      
      fn main() {
          let path = "input.txt";
          let mut file = std::fs::File::open(path).unwrap_or_else(|e| {
              panic!("Failed to read file {}: {}", path, e);
          });
      
          let mut s = String::new();
          file.read_to_string(&mut s).unwrap_or_else(|e| {
              panic!("Failed to read file contents: {}", e);
          });
      
          println!("{}", s);
      }
      

      将您的代码与What's the de-facto way of reading and writing files in Rust 1.x?进行比较。