Rust编程:组织管理和错误处理

Pacakge包含Crate包含Module(二叉树目录结构)

1.Pacakge包含一个Cargo.toml(就是通过cargo new 出来的),它描述了如何构建Crates。只能包含0-1个library crate,可以包含任意多个binary crate,但是必须至少包含一个crate(二者都可)。

2.crate的类型有两种(binary和library),还有一个crate root,这个是rustc编译器开始编译的地方。其中main.rs就是入口文件。src/main.rs是binary crate的crate root。如果还有个src/lib.rs,那么就是library crate,这两个都是crate的根,是mod、fn的根节点。

3.定义module可以来控制作用域和私有性。使用mod来定义。

路径(path)

1.绝对路径和相对路径,中间用::来进行分割。同一级可以直接用模块名来开始。

2.默认情况下:rust里面的所有条目都是私有的(函数,方法,struct,enum,模块,常量),加上pub就可以了。父级模块无法访问子级模块的私有条目,反之则可以。如果是同一文件的同一级,可以不用加pub也可以互相调用。

3.super关键字:上级目录,类似文件系统的…,从模块里面跳到模块外面。

4.pub struct将结构体公共,但是这里面字段还是私有的,需要在字段前面加上pub。枚举变为公共的价格pub就行,里面所有的变体也全变成pub。

use关键字

1.use写一下路径,后面就不必重新全部写路径了。依然遵守私有性规则。

2.as关键字:针对同名模块,必须从他的上级开始写。也可以使用use std::fmt::Result as FmtResult;

3.pub use 也就是外部代码可以直接使用use导入的路径,不用重新导入了。

使用外部包(pacakge)

1.需要在cargo.toml里面添加依赖的包和版本。后面就可以使用use导入即可使用。

2.使用嵌套路径清理大量的use语句,路径相同的部分::{路径差异的部分}。
use std ::{self,cmp::Ordering,io};self就是本身。也可以使用通配符*,和python一样,通常不这样用,会消耗资源和出现版本问题。

3.使用模块名定义在代码里面,模块的名字作为文件的名,然后在那个文件里写模块的详细代码。

错误处理

1.错误的分类:
可恢复的错误:例如文件没找到,可再次尝试。 Result<T,E>
不可恢复的错误:例如bug,访问的索引超出范围。panic!宏

2.当执行一个panic!宏时会执行以下几步:1.你的程序会打印一个错误信息。2.展开(unwind),清理调用栈(stack),这个过程工作量大,rust沿着调用栈往回走,清理每个遇到的函数中的数据。第二步同时也可以设置成立即终止调用栈(abort),不进行清理,直接停止程序,内存由操作系统进行清理。3.退出程序。

3.Result枚举与可恢复的错误
Result枚举:
enum Result<T,E>{
OK(T), T操作成功的情况下,Ok变体里返回的数据
Err(E), E操作失败的情况下,Err变体里返回的数据
}
match匹配不同的错误:

use std::fs::File;
use std::io::ErrorKind;

fn main(){
    let f=File::open("hello.txt");
    let f=match f{
        Ok(file)=>file,
        Err(error)=>match error.kind(){
            ErrorKind::NotFound=>match File::create("hello.txt"){
                Ok(fc)=>fc,
                Err(e)=>panic!("Error createing file:{:?}",e),
            },
            other_error=>panic!("error:{:?}",other_error)
        },
    };
}

4.unwrap方法:let f=File::open("hello.txt").unwrap();作用非常强,和result枚举功能一样,是match表达式的一个快捷方法。
ok返回,err执行panic!
expect:和unwrap类似,但是可以指定错误信息,就是程序错误可以在expect后面写上原因,这就可以定位到错误的位置,而unwrap打印的错误信息都是一样的。注意是错误信息。

5.传播错误:如何将错误返回给调用者。

use std::fs::File;
use std::io;
use std::io::Read;

fn read_username_from_file()->Result<String,io::Error>{
    let f=File::open("hello.txt");

    let mut f=match f{
        Ok(file)=>file,
        Err(e)=>return Err(e)//return 函数就结束。
    };
    let mut s=String::new();
    match f.read_to_string(&mut s){
        Ok(_)=>Ok(s),
        Err(e)=>Err(e),
 }   //这里的match没有分号,是函数返回值。
}

fn main(){
    let result=read_username_from_file();
}

?运算符
如果Result的结果是Ok,Ok中的值就是表达式的结果,然后继续执行程序。
如果Result的结果是Err,Err就是整个函数的返回值,就像使用了return。
?运算符只能用于返回Result的函数。

use std::fs::File;
use std::io;
use std::io::Read;

fn read_username_from_file()->Result<String,io::Error>{
    let f=File::open("hello.txt")?;
    let mut s=String::new();
    f.read_to_string(&mut s)?;
    Ok(s) //如果前面都执行成功,这里返回一个成功值。
}

fn main(){
    let result=read_username_from_file();
}

其中

let f=File::open("hello.txt")?;
//这两句语句的作用是一样的。
let mut f=match File::open("hello.txt"){
        Ok(file)=>file,
        Err(e)=>return Err(e)
    };

链式规则,使代码更加简洁。

fn read_username_from_file()->Result<String,io::Error>{
    let mut s=String::new();
    File::open("hello.txt")?.read_to_string(&mut s)?;
    Ok(s)
}

什么时候使用panic?
看个人经验

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值