从·形参·理解ownership

2020-07-17

一 

  • Each value in Rust has a variable that’s called its owner.
  • There can only be one owner at a time.
  • When the owner goes out of scope, the value will be dropped.

传值传址,rust函数中我觉得可以都看成值传递。

对于基础类型,很明显是直接复制,值传递。

对于堆区类型,传递的是‘堆中数据的指针’这种类似的东西,但是rust中一个值同时只能由一个(指针)(变量编译后会替换成指针)指向,当有新的指针指向堆中数据时,旧的指针失效---失去所属权。

那为什么引用也能访问堆中数据,却不会导致 变量(指针)失效呢?

因为引用并没有直接指向堆,而是栈中开辟一个新的变量指向栈中的那个指针,并没有!直接!指向!堆!

fn main(){
	//栈中会开辟一个存储单元A,存储的内容是 堆中的实际内容 "ficl"。
	//编译后就没有变量这个玩意了,会把上面那个存储单元A的地址 替换掉 s。	
    let s:String=String::from("ficl");
    //函数change会开辟自己 栈中的变量,执行方法时,存储单元中存储的实际地址,复制到 分配给s_tem的存储单元B中。
    //这个时候其实A和B中存储的应该都是堆中数据的实际地址,但是rust的borrow机制就禁止了 旧的指针A。
    change(s);
    //println!("{}",s)//value borrowed here after move
}
fn change(s_tem:String){
    println!("{}",s_tem);
}
fn main(){
	//对于基本类型,内容分配在栈中存储单元A里
    let i=21;
    //因为数据内容就在栈中复制的很快,所以传递给方法时直接复制这个 存储单元A 到 存储单元B中即可。
    //所以A、B中都是 21。
    //是不是违背了第二条 only be one owner at a time呢?
    //我觉得,第二条应该是针对堆中数据,堆中数据只能由一个指针(变量)指向。
    change(i);
    println!("{}",i);
}
fn change(i:i32){
    println!("{}",i)
}

二 引用类型

fn main(){
    let s:String=String::from("ficl");
    change(&s);
    println!("{}",s)//
}
fn change(s:&String){
    println!("{}",s);
}

这里相当于复制了一份 s存储单元A的地址 到 存储单元B(不是A中的值),s还是指向堆中内容"ficl",新s->s->"ficl",所以新s能够顺着"地址链"找到"ficl",且s并不会失去ownership。

三 声明周期--避免悬垂指针

fn main(){
    let company = Company{
        name:String::from("fff")
    };
    let me = Human{
        name:String::from("Ty"),
        company:&company
    };
    {
        let fuck = &company;//如果直接move会编译失败,因为compony的生命周期结束了 但是me中还有他的引用
    }
    println!("{}",me.company.name)
}


struct Company{
    name:String
}
struct Human<'a>{
    name:String,
    company:&'a Company
}