Io E0308使用读卡器中的for行从文件中读取行。行()
我是一名经验丰富的开发人员,目前正在自学生锈,我正在编写一个简单的程序来读取文件中的行。我已经前后阅读了Rust std:io、std:result和其他文档,这些代码主要是直接从文档中获取的。我不明白为什么下面的程序不能编译Io E0308使用读卡器中的for行从文件中读取行。行(),io,rust,Io,Rust,我是一名经验丰富的开发人员,目前正在自学生锈,我正在编写一个简单的程序来读取文件中的行。我已经前后阅读了Rust std:io、std:result和其他文档,这些代码主要是直接从文档中获取的。我不明白为什么下面的程序不能编译 use std::io; use std::fs::File; use std::io::BufReader; use std::io::prelude::*; fn main() { File::open("./data/test") .map
use std::io;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
fn main() {
File::open("./data/test")
.map_err(|err| err.to_string())
.and_then( |mut dataFile| {
let mut reader = BufReader::new(dataFile);
for line in reader.lines() {
println!("{}",line.unwrap());
};
});
}
运行cargo build时收到的编译错误为
我正在运行Rust 1.4.0。您不应该使用and_,而应该使用map
正确代码:
File::open("./data/test")
.map_err(|err| err.to_string())
.map(|mut dataFile| {
let mut reader = BufReader::new(dataFile);
for line in reader.lines() {
println!("{}",line.unwrap());
};
});
您可以在两个函数签名中看到它:
fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E>
fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U, E>
这里的关键区别在于,操作op必须在and_then的案例中返回封装在结果中的内容,而不必在map的案例中封装。您的闭包不会返回任何东西,所以在Rust看来它实际上返回了,并且不能匹配结果。但是可以匹配U,这就是为什么第二个签名有效。您不应该使用and\U,而应该使用map
正确代码:
File::open("./data/test")
.map_err(|err| err.to_string())
.map(|mut dataFile| {
let mut reader = BufReader::new(dataFile);
for line in reader.lines() {
println!("{}",line.unwrap());
};
});
您可以在两个函数签名中看到它:
fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E>
fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U, E>
这里的关键区别在于,操作op必须在and_then的案例中返回封装在结果中的内容,而不必在map的案例中封装。您的闭包不会返回任何东西,所以在Rust看来它实际上返回了,并且不能匹配结果。但是,它可以匹配U,这就是为什么第二个签名可以工作。As,并用于转换带有闭包的结果。当您想要更改内部类型时使用map,然后当您想要链接第二个结果而不嵌套它们时使用_
但是,这两种方法都不适合您的案例,因为您没有转换价值。相反,您需要匹配或if-let语句。这些对副作用更合适
此外,Rust使用snake_案例标识符,不需要将任何变量标记为可变的。这些都是编译后您会看到的编译器警告
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
fn main() {
let f = File::open("./data/test")
.map_err(|err| err.to_string());
if let Ok(data_file) = f {
let reader = BufReader::new(data_file);
for line in reader.lines() {
println!("{}", line.unwrap());
};
}
}
As、and用于转换带有闭包的结果。当您想要更改内部类型时使用map,然后当您想要链接第二个结果而不嵌套它们时使用_
但是,这两种方法都不适合您的案例,因为您没有转换价值。相反,您需要匹配或if-let语句。这些对副作用更合适
此外,Rust使用snake_案例标识符,不需要将任何变量标记为可变的。这些都是编译后您会看到的编译器警告
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
fn main() {
let f = File::open("./data/test")
.map_err(|err| err.to_string());
if let Ok(data_file) = f {
let reader = BufReader::new(data_file);
for line in reader.lines() {
println!("{}", line.unwrap());
};
}
}
我将此标记为答案,就好像mdup的答案很有帮助一样。Shepmaster解释了最好的方法是什么,这非常有帮助。好的,刚刚了解了5分钟的限制,因此对上面的拼写表示歉意,现在无法更正。我要补充的是,我最初是基于第4.7节错误处理文档中的examle来编写这段代码的[.我现在明白了他们为什么要使用map,因为在那个例子中,他们实际上是在链接输出。我确实第一次尝试使用匹配,但我在脑海中看到了它们是如何工作的,这真的很有帮助。谢谢我将此标记为答案,好像mdup的答案很有帮助。Shepmaster解释了最好的方法是什么,而它非常有用pful.OK,刚刚发现了5分钟的限制,所以对上面的拼写表示歉意,现在无法更正。我要补充的是,我最初是根据第4.7节错误处理文档中的examle来编写代码的[.我现在明白了他们为什么要使用map,因为在那个例子中,他们实际上是在链接输出。我确实有过第一次尝试使用匹配项,但我在脑海中看到了它们是如何工作错误的,这真的很有帮助。谢谢