• 普通方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main()
{
let s1 = gives_ownership();
//将hello的值转给s1,s1仍然可以使用。
println!("s1 = {}",s1);
let s2 = String::from("hello");
let s3 = takes_and_gives_back(s2);
//因为s2已经转移至s3中,所以s2不能继续使用了
//println!("s2 = {}",s2);
let mut s4 = String::from("Hello");
let s3 = takes_and_gives_back(s4);
let s4 = takes_and_gives_back(s3);
println!("s4 = {}",s4);

}
fn gives_ownership() -> String {
let s = String::from("Hello");
s
}
fn takes_and_gives_back(s: String) -> String {
s
}
  • 引用
    1. 引用要么只能有多个不可变引用,要么只能有一个可变引用(同一时间下)
    2. 引用必须有效,不能使用悬垂引用

实际上引用只是指向原字符串指针的指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//引用:用法&,让我们创建一个指向值的引用,但是并不拥有这个值,当引用离开其值
//指向的作用域并不会被丢弃。因此引用也不能修改原值·
fn calcute length(s: &String) -> usize {
s.len()
}
fn modify_s (s:& mut String) {
s.push_str(",world");
}
fn main() {
let s1 =String::from("Hello");
let mut s2 = String::from("hello");
//let len = calcute_length(s1);
//注释掉的会报错
let len = calcute_length(&s1);
println!("length = {}",len);
//报错
//modify_s(&s2);
//使用借用,借用的格式是在之前添加mut
modify_s(& mut s2);
println!("s2 = {}",s2);

let r1 = &s1;
let r2 = &s1;
println!("r1 = {},r2 = {}",r1,r2);
let r3 = & mut s1;
println!("r3 = {}",r3);
//报错,因为rust不希望同时使用可变引用和不可变引用。可变引用改变后不可变引用的
//值很难处理。也就是说在使用借用之后不能使用可变引用。
//println!("r1 = {},r2 = {},r3 = {}",r1,r2,r3);
}
  • 悬垂引用
1
2
3
4
5
6
7
8
9
fn main() {
let ref_s = dangle();
}
//s此时已经被回收了,再返回它的引用,这个内存中的内容已经回收掉了,所以此时
//咩用
fn dangle() -> &String {
let s = String::from("Hello");
&s
}