Rust 编程语言-4-理解ownership
2022-01-07 本文已影响0人
onemoremile
4.1 理解ownership
Rust的一个核心概念,通过所有权机制,解决了C/C++语言中的野指针,悬挂指针等诸多问题,提供了更高的安全性
规则
- 每一个值都有一个变量是它的所有者
- 同时只能有一个所有者
- 所有者超出使用范围,值被销毁
String类型的内部结构
String内部由三部分组成:1)指向内存中字符串的指针2)长度 3)容量
这三部分信息是存储在栈Stack上的,箭头右侧数据存储在heap堆上
截屏2022-01-07 下午8.01.02.png当执行如下代码时
let s1 = String::from("hello");
let s2 = s1;
s1栈上的三部分数据复制到s2栈上,当 let s2 = s1执行完,编译器认为s1的生命周期结束,此后s1不可用,任何调用编译器会报错,如下代码不能成功执行
let s1 = String::from("hello");
let s2 = s1;
println!("{}, world!", s1); //error here
s1变量发生了移动move,不再可用
截屏2022-01-07 下午8.05.18.png深拷贝deep clone
fn main() {
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2);
}
Copy Trait 类型的变量赋值,不会被销毁,如u32, bool, f64, char, tuple (i32, i32)
4.2 引用和借用
不可变引用&
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
可变引用& mut
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
下面的function编译无法通过
fn main() {
let reference_to_nothing = dangle();
}
fn dangle() -> &String { // dangle returns a reference to a String
let s = String::from("hello"); // s is a new String
&s // we return a reference to the String, s
} // Here, s goes out of scope, and is dropped. Its memory goes away.
// Danger!
dangle()方法返回的是内部变量s的引用,但是s的生命周期在函数最后一行结束,所以返回了一个指向不存在变量的引用,报错!
修改如下可以正常执行
fn no_dangle() -> String {
let s = String::from("hello");
s
}
此时,返回的是执行内部变量s
规则:
- 只能有一个可变引用,可以有无数的不可变引用
- 引用必须永远存在,指向一个存在的地址
4.3 切片slice
let s = String::from("hello");
let len = s.len();
let slice = &s[3..len];
let slice = &s[3..];
&str 切片
fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
&s[..]
}
fn main() {
let mut s = String::from("hello world");
let word = first_word(&s);
s.clear(); // error!
println!("the first word is: {}", word);
}
s.clear()报错,因为first_world()调用的时候,s被不可变的borrow,所以下面不能再次可变借用