结果得到意外的类型参数

2024-06-25

我试图从文件中读取值以创建结构,但遇到了一对奇怪的错误。我的代码的超级基本实现:

extern crate itertools;

use itertools::Itertools;
use std::io::{self, prelude::*, BufReader};
use std::fs::{self, File};

// The struct I will unpack into
struct BasicExample {
    a: String,
    b: String,
    c: String,
    d: String,
}

impl BasicExample {
    pub fn new(a: String, b: String, c: String, d: String} -> Self {
        BasicExample {
            a, b, c, d
        }
    }

    // I'm expecting that reading from the config file might fail, so
    // I want to return a Result that can be unwrapped. Otherwise an Err
    // will be returned with contained value being &'static str
    pub fn from_config(filename: &str) -> io::Result<Self, &'static str> {
        let file = File::open(filename).expect("Could not open file");

        // read args into a Vec<String>, consuming file
        let args: Vec<String> = read_config(file);

        // I transfer ownership away from args here
        let params: Option<(String, String, String, String)> = args.drain(0..4).tuples().next();

        // Then I want to match and return, I could probably do if-let here
        // but I don't have my hands around the base concept yet, so I'll 
        // leave that for later
        match params {
            Some((a, b, c, d)) => Ok(BasicExample::new(a, b, c, d)),
            _ => Err("Could not read values into struct")
        }
    }

    fn read_config(file: File) -> Vec<String> {
        let buf = BufReader::new(file);

        buf.lines()
            .map(|l| l.expect("Could not parse line"))
            .collect()
    }
}

Running cargo check为了确保我没有错过任何内容,我收到以下错误:

error[E0107]: wrong number of type arguments: expected 1, found 2
  --> src/lib.rs:37:60
   |
37 |     pub fn from_config(filename: &str) -> io::Result<Self, &'static str> {
   |                                                            ^^^^^^^^^^^^ unexpected type argument

error: aborting due to previous error

For more information about this error, try `rustc --explain E0107`.

看起来有点奇怪。io::Result应该采取<T, E>,我已经给了它E,所以让我们删除该类型参数并看看会发生什么:

error[E0308]: mismatched types
  --> src/lib.rs:54:22
   |
54 |             _ => Err("Could not read values into AzureAuthentication struct"),
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::io::Error`, found reference
   |
   = note: expected type `std::io::Error`
              found type `&'static str`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

出于某种原因,它真的不满意E我提供的。我是一个完全的 Rust 初学者,所以也许我只是不确定我在看什么。我在这里做错了什么?这itertools所有权技巧是从(ha)借来的这个精彩的答案 https://stackoverflow.com/a/43658017/7867968.

系统详细信息:

  • macOS 10.13.6
  • rustc 1.36.0 (a53f9df32 2019-07-03)
  • 货物 1.36.0 (c4fcfb725 2019-05-15)

这实际上是一个超级基本的错误,但在您了解(并爱上)之前,它看起来很神秘std::io.

简而言之,std::result::Result(结果你知道)!==std::io::Result。第一个的文档是here https://doc.rust-lang.org/std/result/enum.Result.html,而第二个是here https://doc.rust-lang.org/std/io/type.Result.html

您会注意到第二个它实际上是一个类型别名Result<T, std::io::Error>。这意味着它是有效的简写,其中您的错误情况是一个实例std::io::Error.

因此,当您尝试仅执行以下操作时,您的代码是不正确的Err()它带有一个字符串切片(因为该切片不是std::io::Error,显然)。

有多种方法可以解决此问题:

  • 您可以将整个错误链转换为另一种类型(显式或通过利用into() casts)
  • 你可以让你自己的错误返回std::io::Error实例

这两个选项都有有效的案例,这就是我提到这两个选项的原因。第二个相对容易完成,就像这样(完整路径用于文档目的)。假设您返回一个与未找到的实体匹配的错误。你可以这样做:

`Err(std::io::Error::new(std::io::ErrorKind::NotFound, "Could not read values into AzureAuthentication struct"))`

然而,有一个更好的方法来实现你的功能:

pub fn from_config(filename: &str) -> io::Result<Self> {
    let file = File::open(filename)?;
    let args: Vec<String> = read_config(file); // This has no error possibility

    let params: Option<(String, String, String, String)> = args.drain(0..4).tuples().next();
    params.ok_or(std::io::Error::new(std::io::ErrorKind::NotFound, "Could not read values into struct")).map(|(a, b, c, d)| BasicExample::new(a,b,c,d))
}

这消除了方法中的所有间接性,并一一巧妙地折叠了错误类型,因此您不必担心它们。这Option变成了Result谢谢ok_or,一切都很好:-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结果得到意外的类型参数 的相关文章

随机推荐