Rust 编程零基础学习+实战(2)

所有权机制简介

为什么引入所有权

在C语言中,可以使用malloc分配一定大小的内存,再使用free释放分配的内存。这样做存在一个问题,就是当我们把指针传递给一个函数,在函数返回值之后,无法确定指针指向的内存是否已经被释放。函数中有可能已经释放过内存,如果再释放一遍就会出现问题。Rust引入了所有权机制,可以规避这个问题。

什么是所有权

简单来说,所有的变量都有一个所有者(Owner),一般是指所在的函数。当一个函数结束时,除了返回值之外的其他变量都会drop掉,也就是被释放掉。另外,当我们把变量作为参数传递给另一个函数时,这个变量的所有权会发生改变,传递给被调用的函数,在原函数中不能再使用该变量。

代码

#[derive(Copy, Clone)]
struct Foo {
    x: i32,
    y: usize,
    z: Option<f64>,
}

fn main() {
    let x = 42;
    let y = x;

    println!("{x}");

    let x = Box::new(42);
    let y = x.clone();

    println!("{x}");

    let foo1 = Foo { x: 42, y: 123, z: None };
    let foo2 = foo1;
    
    println!("{}", foo1.x);

    let ptr = give_me_int();
    print_int(ptr.clone());

    println!("{ptr}");
}

fn print_int(ptr: Box<i32>) {
    println!("{ptr}");
    // drop(ptr);
}

fn give_me_int() -> Box<i32> {
    Box::new(42)
}

其中,Box起到分配内存的作用,drop相当于C语言中的free函数。

在give_me_int()函数中,一个值为42的i32类型变量被创建,第一个所有者是give_me_int()。

之后返回给main,所有者变为main,变量名是ptr。

再之后传递给print_int()函数。如果这里直接传递ptr,那么所有者会转变为print_int()。而print_int()不返回任何变量,会drop掉传入的ptr,因此ptr就此消失,在原先的main中将无法执行println!("ptr")。

因此使用了ptr.clone()方法,简单理解就是复制了一份传过去,这样跟原先的ptr就没有关系了。

值得注意的是,println!()不改变参数所有者。

这段代码还有一部分是关于Foo结构体,可以看到main函数中创建了foo1,又赋值给foo2,再之后又使用的foo1.x。可以这么做,是因为在定义Foo结构体时,用到#[derive(Copy, Clone)],允许Copy和Clone,因此foo1赋值给foo2时会有复制的过程,foo1仍旧拥有资源。如果不允许复制,那么foo1赋值给foo2后,foo1不再被允许访问资源x。

Match 关键字

match相当于C语言中的switch语句,写法略有不同。使用match时应当注意default情况,使用的是下划线 _ 作为default情况,类似python中 _ 的用法。

let a = 1;
match a {
    1 => { println!("1"); }
    2 => { println!("2"); }
    _ => { println!("3"); }
}

match还可以用于赋值等。

添加库

在Rust中库被称为crate。打开Cargo.toml文件,可以看到[dependencies],这部分就是已经添加的库的名称,可以使用如下命令添加。

cargo add yourcratename

标准输入输出

std::io::stdin()和std::io::stdout()可以创建两个对象,使用对象中的方法可以进行标准输入输出。可以参考stdin in std::io - Ruststdout in std::io - Rust

在开始执行程序时也可以输入参数,可以使用std::env::args()创建的对象获取。参考args in std::env - Rust

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值