1. 引用和借用
1. 引用:允许你获取值的使用权而非所有权。使用符号&传递和接收引用参数。
示例:当以普通的方式,将作用域内的变量以参数的方式传递给某个函数,那么在此之后将无法访问该变量,因为其已经被移动(move)了,使用引用来解决这种情况。
rust
fn main(){
let s = String::from("hello");
let len = calculate_length(&s);
println!("The length of '{}' is {}.", s, len);//
}
pub fn calculate_length(s:&String) -> usize{
s.len()
}2. 借用:创建引用的行为(过程)为借用。借用不获取变量的是所有权,所以也无需返回所有权。
2. 可变引用
当尝试对引用作出修改会发生什么?尝试以下代码:
rust
fn main(){
let s = String::from("hello");
let z = change_s(&s);
pintln!("changed s:{}.", z);//
}
pub fn change_s(s:&String){
s.push_str(",word")
}这种操作将收到报错:cannot borrow *sas mutable, as it is behind a& reference,panic信息提示不可对引用变量s作为可变借用。 尝试声明可变引用来解决上述问题,在传递和接受时修改参数签名为mut,诸如:
rust
fn main(){
let s = String::from("hello");
let z = change_s(&mut s);
pintln!("changed s:{}.", z);//"hello,word"
}
pub fn change_s(s:&mut String){
s.push_str(",word")
}注意:在同一时间,只能有一个对某一特定数据的可变引用。
rust
let mut s = String::from("hello");
let r1 = &s; // 没问题
let r2 = &s; // 没问题
let r3 = &mut s; // 大问题
println!("{}, {}, and {}", r1, r2, r3);shell
$ cargo run
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> src/main.rs:6:14
|
4 | let r1 = &s; // no problem
| -- immutable borrow occurs here
5 | let r2 = &s; // no problem
6 | let r3 = &mut s; // BIG PROBLEM
| ^^^^^^ mutable borrow occurs here
7 |
8 | println!("{}, {}, and {}", r1, r2, r3);
| -- immutable borrow later used here3. slice切片
slice切片是一种没有所有权的数据类型。它允许引用集合中一段连续的元素序列,而不用引用整个集合。
1. 字符串slice
字符串 slice(string slice)是 String 中一部分值的引用,对字符串字面量&str可同样使用slice引用。形式诸如:
rust
let x = String::from("hello word");
//语法&vac[startIndex..endIndex]
let first_word = &x[..5] //当起始索引为0时,可省略
let first_word = &x[6..] //当结束索引为末尾时,可省略
let first_word = &x[5..6] /常规注意:字符串字面量本身就是slice
2. slice作为参数传递
使用字符串字面量作为参数类型可以同时满足字面量和String两种参数,而不用额外添加新函数。
rust
fn main(){
let x = "hello word";
let z = String::from("hello,word");
let x_one = first_word(&x);//
let z_one = first_word(&z);
}
pub fn first_word(s:&str) -> &str{
for(i,&item) in s.as_bytes().iter().enumerate(){
if(item == b' '){
return &s[..i]
}
}
&s[..]
}