Rust从1.13版对语言进行了一些扩展,包括期待已久的?操作符。今天重点来谈谈?操作符。
最初,加入了一个新的操作符?,是为了简化Result
fn read_username_from_file() -> Result<String, io::Error> {
let f = File::open("username.txt");
let mut f = match f {
Ok(file) => file,
Err(e) => return Err(e),
};
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
有了?操作符:
fn read_username_from_file() -> Result<String, io::Error> {
//对象本身返回类型就是Result; 且在Result类函数体内
let mut f = File::open("username.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
use std::fs::File;
use std::io::prelude::*;
use std::io;
struct Info {
name: String,
age: i32,
rating: i32,
}
fn write_info(info: &Info) -> io::Result<()> {
// Early return on error
let mut file = match File::create("my_best_friends.txt") {
Err(e) => return Err(e),
Ok(f) => f,
};
if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) {
return Err(e)
}
if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) {
return Err(e)
}
if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) {
return Err(e)
}
Ok(())
}
有了?操作符,可以改成下面:
use std::fs::File;
use std::io::prelude::*;
use std::io;
struct Info {
name: String,
age: i32,
rating: i32,
}
fn write_info(info: &Info) -> io::Result<()> {
let mut file = File::create("my_best_friends.txt")?;
// Early return on error
file.write_all(format!("name: {}\n", info.name).as_bytes())?;
file.write_all(format!("age: {}\n", info.age).as_bytes())?;
file.write_all(format!("rating: {}\n", info.rating).as_bytes())?;
Ok(())
}
细查一下write_all:
use std::io;
trait Write {
fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>;
}
还有:File::create
pub fn create<P: AsRef<Path>>(path: P) -> Result<File>
感觉幸福了不少。
注意:test_io函数体中的内容不能直接放到main函数中。因为不符合我们前面提的几个条件,main函数的返回为(),不是Result或Option类型,或实现了Try trait。
use std::fs::File;
use std::io::prelude::*;
fn main() {
let st = SystemTime::now();
println!("i will go asleep!");
test_io("C:\\Users\\wowotuo\\Desktop\\test.txt");
let et =SystemTime::now();
thread::sleep_ms(500000);
}
fn test_io(s:&str)->io::Result<()>{
let mut f = File::create(s)?;
f.write_all(b"Hello, world!")?;
f.sync_data()?;
Ok(())
}
二、发展至Option
从1.22版本开始,为了简化Option类型的处理,最新版本的Rust允许在Option类型上使用?操作符了。