All data stored on the stack must have a known, fixed size. Data with an unknown size at compile time or a size that might change must be stored on the heap instead.
Pushing to the stack is faster than allocating on the heap because the allocator never has to search for a place to store new data;
Ownership Rules
解决堆上数据 的问题
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. 从堆中回收
string 存在scope中
the concept of copying the pointer, length, and capacity without copying the data probably sounds like making a shallow copy.
rust
1 2 3 4
let s1 = String::from("hello"); | -- move occurs because `s1` has type `std::string::String`, which does not implement the `Copy` trait 3 | let s2 = s1; | -- value moved here
s1 无效 回收只s2
1 2 3 4 5 6 7
fn main() { let s1 = String::from("hello"); let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2); }
1 2
x=5 y=x
栈中不用clone
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
fn main() { let s = String::from("hello"); // s comes into scope
takes_ownership(s); // s's value moves into the function... // ... and so is no longer valid here let x = 5; // x comes into scope makes_copy(x); // x would move into the function, // but i32 is Copy, so it’s okay to still // use x afterward } // Here, x goes out of scope, then s. But because s's value was moved, nothing // special happens.
{ let r1 = &mut s; } // r1 goes out of scope here, so we can make a new reference with no problems. let r2 = &mut s; }
用花括号创建一个空间,来引用,
We also cannot have a mutable reference while we have an immutable one. 可变变量有不变引用后,不能创建可变引用
1 2 3 4 5 6 7 8 9 10 11
fn main() { let mut s = String::from("hello");
let r1 = &s; // no problem let r2 = &s; // no problem println!("{} and {}", r1, r2); // r1 and r2 are no longer used after this point let r3 = &mut s; // no problem println!("{}", r3); }
引用范围从创建到最后一次使用 关键是不重叠
1 2 3 4 5 6 7 8 9 10 11
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!
slice
1 2 3 4 5 6 7 8 9 10 11
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() }
iter is a method that returns each element in a collection enumerate wraps the result of iter and returns each element as part of a tuple instead. 第一个参数是索引值,第二个是值的引用
1 2 3 4 5 6
fn main() { let s = String::from("hello world");
let hello = &s[0..5]; //0可以省去 let world = &s[6..11]; 存6-10 }
string slices
1 2 3 4 5 6 7 8
fn main() { let s = String::from("hello");
let len = s.len();
let slice = &s[3..len]; let slice = &s[3..]; //相同 }
The type that signifies “string slice” is written as &str:
1 2 3 4 5 6 7 8 9 10 11 12
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[..] }
String Literals Are Slices 固定字符串就是一种切片 The type of s here is &str it’s a slice pointing to that specific point of the binary
fn main() { let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active:true, sign_in_count:1, };
let user2 = User { email: String::from("another@example.com"), username: String::from("anotherusername567"), ..user1 // .. specifies that the remaining fields not explicitly set should have the same value as the fields in the given instance. }; }