// TODO: Fix the compiler error in this function.
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let vec = vec;
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics1() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
}
解题要点
错误原因 : 函数参数 vec 已经移动到函数内部,不需要重新赋值
解决方法 : 直接使用参数 vec,去掉多余的重新赋值
正确写法
rust复制代码
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics1() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
}
move_semantics2.rs - 所有权保留
问题代码
rust复制代码
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
// TODO: Make both vectors `vec0` and `vec1` accessible at the same time to
// fix the compiler error in the test.
#[test]
fn move_semantics2() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec0, [22, 44, 66]);
assert_eq!(vec1, [22, 44, 66, 88]);
}
}
解题要点
错误原因 : vec0 被移动到 fill_vec 函数后,在测试中无法再使用
解决方法 : 传递 vec0 的引用而不是所有权,或者克隆向量
正确写法
rust复制代码
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics2() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0.clone());
assert_eq!(vec0, [22, 44, 66]);
assert_eq!(vec1, [22, 44, 66, 88]);
}
}
move_semantics3.rs - 可变绑定
问题代码
rust复制代码
// TODO: Fix the compiler error in the function without adding any new line.
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics3() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, [22, 44, 66, 88]);
}
}
解题要点
错误原因 : 函数参数 vec 是不可变的,但 push 方法需要可变引用
解决方法 : 将参数声明为可变的 let mut vec = vec
正确写法
rust复制代码
fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
vec.push(88);
vec
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics3() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, [22, 44, 66, 88]);
}
}
move_semantics4.rs - 可变引用冲突
问题代码
rust复制代码
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
// TODO: Fix the compiler errors only by reordering the lines in the test.
// Don't add, change or remove any line.
#[test]
fn move_semantics4() {
let mut x = Vec::new();
let y = &mut x;
let z = &mut x;
y.push(42);
z.push(13);
assert_eq!(x, [42, 13]);
}
}
解题要点
错误原因 : 同时存在两个可变引用 y 和 z 指向同一个数据,违反借用规则
解决方法: 重新排列代码,确保同一时间只有一个可变引用
正确写法
rust复制代码
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
#[test]
fn move_semantics4() {
let mut x = Vec::new();
let y = &mut x;
y.push(42);
let z = &mut x;
z.push(13);
assert_eq!(x, [42, 13]);
}
}
move_semantics5.rs - 引用与所有权
问题代码
rust复制代码
#![allow(clippy::ptr_arg)]
// TODO: Fix the compiler errors without changing anything except adding or
// removing references (the character `&`).
// Shouldn't take ownership
fn get_char(data: String) -> char {
data.chars().last().unwrap()
}
// Should take ownership
fn string_uppercase(mut data: &String) {
data = data.to_uppercase();
println!("{data}");
}
fn main() {
let data = "Rust is great!".to_string();
get_char(data);
string_uppercase(&data);
}