所有权与函数
fn main() {
let s = String::from("hello");
takes_ownership(s); //s的值移动到函数里
let x = 5; //x进入作用域
makes_copy(x); //x应该移动到函数里,但是i32是copy,所以后面可以继续使用x。
println!("x is {}",x);
//下面这句编译会出错, ^ value borrowed here after move
//println!("s is {}",s);
}
fn takes_ownership(some_string:String){
println!("{}",some_string);
} //some_string离开作用域并调用drop方法。占用的内存释放
fn makes_copy(some_integer: i32) {
println!("{}",some_integer);
}
返回值与作用域
fn main() {
let s1 = gives_ownership(); //函数返回值some_string移动给s1
let s2 = String::from("hello"); //s2进入作用域
let s3 = take_and_give_back(s2); //s2移动但函数,然后移交给s3。最终只有s3有效
}
fn gives_ownership() -> String {
let some_string = String::from("hello");
some_string //因为some_string是String类型,所以这里做移动操作
}
fn take_and_give_back(a_string: String) -> String {
a_string
}
引用的使用
//为了能够返回函数的值以及其值的一些属性,我们可以使用引用
//类似go的指针吧,只获取值不获取所有权。
fn main() {
//因为默认不允许修改引用的值,所以加mut。
let mut s = String::from("hello world");
//let s1 = &mut s;
//但是要注意:在特定作用域中的特定数据有且只有一个可变引用。
//s1已经引用了,s2就不能再用,避免了数据竞争
//let s2 = &mut s;
// println!("{}", s1);
//可以使用大括号来创建一个新的作用域,s1和s2的作用域不同。
{
let s1 = &mut s;
println!("s1 {}", s1);
}
let s2 = &mut s;
println!("s2{}", s2);
// change(&mut s);
}
// fn change(some_string: &mut String){
// some_string.push_str(",world");
// }
注意:同一个区域不允许可变和不可变引用同时存在例如下面这样
let mut s = String::from("hello world");
let s1=&s;
let s2=&s;
//println("{},{}",s1,s2); //s1,s2调用之后失效,下面的可变引用s3才能生效。
let s3=&mut s;