rust4所有权

rust生命周期+所有权+借用检查,直面内存安全问题

把值压到stack上不叫分配,因为位置永远在stack的顶端,

挨着放就行。

fn main() { let s = String::from("hello world"); take_ownership(s);//s被移动到函数里面,从这以后s不再有效,所以下面打印就会报错 // println!("{}", s);//报错 let x = 6; makes_copy(x);//x是i32类型,i32实现了Copy Trait,所以往函数里面传的是x的副本 println!("{}", x);//x只是copy,所以这里还能打印 } fn makes_copy(num: i32) { println!("{}", num); } fn take_ownership(str: String) { println!("{}", str); }

fn main() { let s1 = String::from("hello world"); //引用s1但并不拥有s1,因为这个&s1并不拥有s1,所以当它走出作用域的时候,它指向的值并不会被清理掉 let len = calculate_length(&s1); println!("the length of {} is: {}", s1, len); } fn calculate_length(s: &String) -> usize { s.len() }//走到这s就出了作用域,但是由于它并不具有它所指向字符串的所有权,所以它所指向的值不会被清理掉, //跟其他参数一样,s的作用域还是那么大,但与其他参数不同的是,它不会在离开自己作用域的时候销毁其指向的数据 //因为它并不拥有该数据的所有权。 //所以当一个函数使用引用作为参数而不是真实的值作为参数的时候,我们就不必为了归还所有权,而把这个值 返回回去, //因为在这种情况下,我们就根本没有获得所有权,而这种以引用作为函数参数的行为,我们就把它称为借用,s在第八行结束后就已经除了作用域,就会被销毁了,而对s的引用却返回了,所以这个引用指向一个已被释放的内存地址,这就是悬空指针。

rust在编译的时候就会报错,防止这种悬空指针。

上图的意思,比如汉字在UTF8编码中占3个字节

fn main() { let s = String::from("hello world"); let word_index = first_word(&s); // s.clear(); println!("s={} index={}", s, word_index); } fn first_word(s: &String) -> usize { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return i; } } s.len() }

fn main() { let mut s = String::from("hello world"); let word_index = first_word(&s); s.clear(); println!("s={} index={}", s, word_index); } fn first_word(s: &String) -> usize { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return i; } } s.len() }

fn main() { let mut s = String::from("hello world"); let word_index = first_word(&s); s.clear(); println!("s={} index={}", s, word_index); } fn first_word(s: &String) -> &str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[..i]; } } &s[..] }

上面就会报错

error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable --> src/main.rs:4:5 | 3 | let word_index = first_word(&s); | -- immutable borrow occurs here 4 | s.clear(); | ^^^^^^^^^ mutable borrow occurs here 5 | println!("s={} index={}", s, word_index); | ---------- immutable borrow later used here

那为什么之前的(代码如下)不报错呢?

fn first_word(s: &String) -> usize { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return i; } } s.len() }

因为这个s的不可变引用在first_word函数结束的时候已经失效,

但是上面报错的是返回了切片,切片是对s的一部分引用,返回后,就和s.clear()这个可变引用在同一个作用域了

从上图可以看出s.clrear() 其实等价于clear($mut s)

fn main() { let s = String::from("hello world"); let word = first_word(&s[..]); println!("s={} index={}", s, word); let s2="hello world"; let word2 = first_word(s2); println!("s={} index={}", s2, word2); } fn first_word(s: &str) -> &str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[..i]; } } &s[..] }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值