Rust 学习笔记(一)

Options类型和错误处理

enum Option {

None,

Some(T),

}

Option 系统类型,可以传入任何值 ,包含 2个函数 Some() Noe() 通过匹配 match 可以获取到 内部的值,这样可以避免 直接 访问 变量本身, 如 在 如c这样语言里 如果直接 使用了nil的指针 会报错,在Rust里面 我们 不直接使访问,而是通过间接的 通过系统函数match 来匹配 如果为 空 匹配的就是None 的处理方法。

代码示例:

let a:Option<f32> = Some(100.111);
match a {
   Some(i) => {
       println!("{}",i);
   },
    None =>{
        println!("has no value");
    }
}
let a1:Option<f32> = Option::None;
match a1 {
    Some(i) => {
        println!("{}",i);
    },
    None =>{
        println!("has no value");
    }
}
unwrap
下面代码,就是Option 对 空的检查, 类比 Go语言里面的 if var == nil{panic(”error“)} 。
impl<T> Option<T> {
    fn unwrap(self) -> T {
        match self {
            Option::Some(val) => val,
            Option::None =>
                panic!("called `Option::unwrap()` on a `None` value"),
        }
    }
}
unwrap_or

对于None的处理情况,我们可以提供一个默认值作为返回。

fn unwrap_or<T>(option: Option<T>, default: T) -> T {
    match option {
        None => default,
        Some(value) => value,
    }
}
 print!("{}",unwrap_or(a1, 1 as f32)); //如果为None 默认返回1

and_then
fn and_then<F, T, A>(option: Option<T>, f: F) -> Option<A>
    where F: FnOnce(T) -> Option<A> {
    match option {
        None => None,
        Some(value) => f(value),
    }
}

与map类似,但返回的是另一个Option。

Result

enum Result<T, E> {
    Ok(T),
    Err(E),
}

与Options类似,它包含了,返回结果 或者 错误产生的原因。

unwrap
impl<T, E: ::std::fmt::Debug> Result<T, E> {
    fn unwrap(self) -> T {
        match self {
            Result::Ok(val) => val,
            Result::Err(err) =>
                panic!("called `Result::unwrap()` on an `Err` value: {:?}", err),
        }
    }
}

和Options 类似大同小异,None 变成了 Error的原因。

查找
文本搜素类
//寻找文本的索引
fn extension(file_name: &str) -> Option<&str> {
    find(file_name, '.').map(|i| &file_name[i+1..])
}
Rust 迭代
let mut v =  vec![1, 2, 3, 4, 5, 6, 7];
let  mut  m = **v.get(1).unwrap().borrow_mut();
for  x in  v.iter_mut(){
    *x += 2;
}

取数组第N个元素

let mut v =  vec![1, 2, 3, 4, 5, 6, 7];
let  mut  m = v.get_mut(2).unwrap();
*m = 100;
Rust Vec

Vec 包含(指针容量长度)

pub struct Vec<T> {
    ptr: *mut T,
    cap: usize,
    len: usize,
}

Vec::with_capacity(0)

随机访问

不安全访问(直接通过下标):

​ vec[index]

安全访问:

vec.get(i)

引用和可变引用

一个数据同时可以有多个引用,同时只能存在一个可变借用,而且一旦 存在可变借用那么之前所有的可变引用将会变得无法使用(编译器报错),如果有一个可变借用那么将无法再.

let mut a = String::from("xiaoming");
let b =  & mut a; //可变引用
let c = a; //在 b 借用了 a 之后 再引用 a
b.push("a".parse().unwrap()); //改变 b的值

println!("{}",a);
println!("{}",b);
println!("{}",c);

上述代码就是违反了,定义所以无法通过!

定义数据结构
#[derive(Debug)]
struct User{
    name:String,
    count:String,
    nonce:u64,
    active:bool,
}
let mut m = User{ name: String::from("xiaoming"),count:String::from("99"),nonce:34,active:false};
m.name = String::from("caomao");//修改可变结构体
println!("{:?}",m);//打印输出
切片
let s =String::from("hello world!");
let h = &s[0..5]; //前五个字节 左闭右开
let h = &s[0..=4];//0 到 4个字节
let h = &s[..=4];//五四个字节
let h = &s[..];//取全部
println!("h= {}",h);
Box堆上空间

Box 是通过创建一个指针的方式,将内容生成在堆上,而指针指向对的空间。 对比Vec 通过 Box 内存消耗更多,但是通过指针的好处是 不管你是一个i32 string还是对象 都可以通过一个固定大小的指针来声明,在许多面向对象的 语言里面,Java/Python/Ruby/JavaScript 等都是通过Box指针这种方式实现的。

Vec<i32>

(stack)    (heap)
┌──────┐   ┌───┐
│ vec1 │──→│ 1 │
└──────┘   ├───┤
           │ 2 │
           ├───┤
           │ 3 │
           ├───┤
           │ 4 │
           └───┘
Vec<Box<i32>>

(stack)    (heap)   ┌───┐
┌──────┐   ┌───┐ ┌─→│ 1 │
│ vec2 │──→│   │─┘  └───┘
└──────┘   ├───┤    ┌───┐
           │   │───→│ 2 │
           ├───┤    └───┘
           │   │─┐  ┌───┐
           ├───┤ └─→│ 3 │
           │   │─┐  └───┘
           └───┘ │  ┌───┐
                 └─→│ 4 │
                    └───┘

在python里面的list 可以存放任何类型对象,实现上与Vec<Box>也是类似的。

有的时候编译器不能在编译期间确定数据大小 如Vec String,也就无法计算出在栈上需要分配多少空间,而通过指针 即使不确定数据类型的大小,但是可以在运行时分配在栈上,指针作为引用,这样大小就是可知的可以分配在栈上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值