ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

std1.97.1——result模块总览

std1.97.1——result模块总览 目录0. Result模块简介1. Result必须被使用(Rust程序设计语言中提过了)2. 问号运算符?3. 内存表示(暂时不知道这部分讲得什么玩意)参考0. Result模块简介使用Result类型进行错误处理。ResultT, E是用于返回和传播错误的类型。它是一个枚举包含变体Ok(T)表示成功并包含一个值以及Err(E)表示错误并包含一个错误值。enumResultT,E{Ok(T),Err(E),}函数在预期出现可恢复错误时返回Result。在std crate中Result最常用于I/O。一个返回Result的简单函数可以如下定义和使用#[derive(Debug)]enumVersion{Version1,Version2,}fnparse_version(header:[u8])-ResultVersion,staticstr{matchheader.get(0){NoneErr(invalid header length),Some(1)Ok(Version::Version1),Some(2)Ok(Version::Version2),Some(_)Err(invalid version),}}fnmain(){letversionparse_version([1,2,3,4]);matchversion{Ok(v)println!(working with version: {v:?}),Err(e)println!(error parsing header: {e:?}),}}1. Result必须被使用(Rust程序设计语言中提过了)使用返回值指示错误的一个常见问题是很容易忽略返回值从而导致错误未被处理。Result被标注了#[must_use]属性当Result值被被忽略时编译器会发出警告。这使得Result特别适合于那些可能遇到错误但不返回有用值的函数。考虑为I/O类型定义write_all方法它属于Write traitusestd::io;traitWrite{fnwrite_all(mutself,bytes:[u8])-Result(),io::Error;}这个方法不产生值但写入可能失败。处理错误情况至关重要不要写成这样usestd::fs::File;usestd::io::prelude::*;fnmain(){letmutfileFile::create(valuable_data.txt).unwrap();// 如果write_all出错我们将永远不知道因为返回值被忽略了。file.write_all(bimportant message);}如果你在Rust中这样写编译器会给你一个警告。如果你不想处理错误可以用expect简单地断言成功。如果写入失败它会panic并提供一个大致有用的消息说明原因。usestd::fs::File;usestd::io::prelude::*;fnmain(){letmutfileFile::create(valuable_data.txt).unwrap();file.write_all(bimportant message).expect(failed to write message);}用?将错误向上传播到调用栈fnwrite_message()-io::Result(){letmutfileFile::create(valuable_data.txt)?;file.write_all(bimportant message)?;Ok(())}2. 问号运算符?当编写调用许多返回Result类型函数的代码时错误处理可能很繁琐。问号运算符?隐藏了一些将错误向上传播到调用栈的样板代码。它将这段代码usestd::fs::File;usestd::io::prelude::*;usestd::io;structInfo{name:String,age:i32,rating:i32,}fnwrite_info(info:Info)-io::Result(){// 出错提前返回letmutfilematchFile::create(my_best_friends.txt){Err(e)returnErr(e),Ok(f)f,};ifletErr(e)file.write_all(format!(name: {}\n,info.name).as_bytes()){returnErr(e);}ifletErr(e)file.write_all(format!(age: {}\n,info.age).as_bytes()){returnErr(e);}ifletErr(e)file.write_all(format!(rating: {}\n,info.rating).as_bytes()){returnErr(e);}Ok(())}替换为usestd::fs::File;usestd::io::prelude::*;usestd::io;structInfo{name:String,age:i32,rating:i32,}fnwrite_info(info:Info)-io::Result(){// 出错时提前返回letmutfileFile::create(my_best_friends.txt)?;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(())}在表达式末尾加上?如果结果是Ok则获取其解包后的值如果是Err则提前从外层函数返回该Err。?可用于返回Result的函数因为它提供了Err的提前返回功能。3. 内存表示(暂时不知道这部分讲得什么玩意)Rust保证当T或E中有一个类型满足Option的内存表示保证(称该类型为I)且另一个类型是大小为零且对齐为1的类型(即1-ZST)时ResultT, E与I(因此也与OptionI)具有相同的大小、对齐和ABI。如果I是T那么将类型为I的值t transmute为ResultT, E(得到Ok(t))以及将类型为ResultT, E的值Ok(t) transmute为类型I(得到值t)没有运行时开销。如果I是E同理只是将Ok替换为Err。参考1、Rust std::result
返回列表