21.使用()对变量进行解包
// primitive_types5.rs
// Destructure the `cat` tuple so that the println will work.
// Execute `rustlings hint primitive_types5` or use the `hint` watch subcommand for a hint.
fn main() {
let cat = ("Furry McFurson", 3.5);
// 这里要使用()解包 而不是{}解包
let (name,age)= cat;
println!("{} is {} years old.", name, age);
}
22.元组的下标引用
使用.index来进行下标索引,注意数组依旧采取[index]的方式来进行下标索引
// primitive_types6.rs
// Use a tuple index to access the second element of `numbers`.
// You can put the expression for the second element where ??? is so that the test passes.
// Execute `rustlings hint primitive_types6` or use the `hint` watch subcommand for a hint.
#[test]
fn indexing_tuple() {
let numbers = (1, 2, 3);
// Replace below ??? with the tuple indexing syntax.
let second = numbers.1;
assert_eq!(2, second,
"This is not the 2nd number in the tuple!")
}
23.使用Vec!来创建数组
注意是小写的vec!
// vecs1.rs
// Your task is to create a `Vec` which holds the exact same elements
// as in the array `a`.
// Make me compile and pass the test!
// Execute `rustlings hint vecs1` or use the `hint` watch subcommand for a hint.
fn array_and_vec() -> ([i32; 4], Vec) {
let a = [10, 20, 30, 40]; // a plain array
let v = vec![10, 20, 30, 40];// TODO: declare your vector here with the macro for vectors
(a, v)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_array_and_vec_similarity() {
let (a, v) = array_and_vec();
assert_eq!(a, v[..]);
}
}
24.Vec和map的遍历迭代
// vecs2.rs
// A Vec of even numbers is given. Your task is to complete the loop
// so that each number in the Vec is multiplied by 2.
//
// Make me pass the test!
//
// Execute `rustlings hint vecs2` or use the `hint` watch subcommand for a hint.
fn vec_loop(mut v: Vec) -> Vec {
for i in v.iter_mut() {
// TODO: Fill this up so that each element in the Vec `v` is
// multiplied by 2.
*i*=2;
}
// At this point, `v` should be equal to [4, 8, 12, 16, 20].
v
}
fn vec_map(v: &Vec) -> Vec {
v.iter().map(|num| {
// TODO: Do the same thing as above - but instead of mutating the
// Vec, you can just return the new number!
num*2
}).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec_loop() {
let v: Vec = (1..).filter(|x| x % 2 == 0).take(5).collect();
let ans = vec_loop(v.clone());
assert_eq!(ans, v.iter().map(|x| x * 2).collect::>());
}
#[test]
fn test_vec_map() {
let v: Vec = (1..).filter(|x| x % 2 == 0).take(5).collect();
let ans = vec_map(&v);
assert_eq!(ans, v.iter().map(|x| x * 2).collect::>());
}
}
25.可变借用
开始vec1没有生命mut 所以push会报错 ,加上mut申明即可
// move_semantics1.rs
// Execute `rustlings hint move_semantics1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: Vec) -> Vec {
let mut vec = vec;
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
26.不能修改传入给函数的参数,但是可以修改其克隆体(应该是这样??)
Rust不允许在默认情况下修改传递给函数的参数,但当你明确地创建一个克隆(clone)时,你可以在函数内部对克隆进行修改,因为克隆是一个独立的拥有者。
// move_semantics2.rs
// Make me compile without changing line 13 or moving line 10!
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0.clone());
// Do not change the following line!
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: Vec) -> Vec {
let mut vec = vec;
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
27.全部变成mut,解决所有烦恼
// move_semantics3.rs
// Make me compile without adding new lines-- just changing existing lines!
// (no lines with multiple semicolons necessary!)
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn main() {
let mut vec0 = Vec::new();
let mut vec1 = fill_vec(&mut vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: &mut Vec) -> &mut Vec {
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
28.不传入参数,在函数内部创建vector
这里是题目要求
// move_semantics4.rs
// Refactor this code so that instead of passing `vec0` into the `fill_vec` function,
// the Vector gets created in the function itself and passed back to the main *******!!!
// function.
// Execute `rustlings hint move_semantics4` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn main() {
// let vec0 = Vec::new();
let mut vec1 = fill_vec();
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
// `fill_vec()` no longer takes `vec: Vec` as argument
fn fill_vec() -> Vec {
// let mut vec = vec;
let mut vec=Vec::new();
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
29.不能同时存在多个可变引用
// move_semantics5.rs
// Make me compile only by reordering the lines in `main()`, but without
// adding, changing or removing any of them.
// Execute `rustlings hint move_semantics5` or use the `hint` watch subcommand for a hint.
// 在任何给定时间,要么只能有一个可变引用,要么可以有多个不可变引用。
// 不可变引用和可变引用之间是互斥的,不能同时存在。
fn main() {
let mut x = 100;
let y = &mut x;
*y += 100;
let z = &mut x;
*z += 1000;
assert_eq!(x, 1200);
}
30.传递引用,避免对非mut申明变量的引用,通过覆盖变量达到避免对原参数的修改
// move_semantics6.rs
// Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand for a hint.
// You can't change anything except adding or removing references.
// I AM NOT DONE
fn main() {
let data = "Rust is great!".to_string();
get_char(&data);
string_uppercase(&data);
}
// Should not take ownership
// fn get_char(data: String) -> char 这样会获取所有权
fn get_char(data: &String) -> char {
data.chars().last().unwrap()
}
// Should take ownership
fn string_uppercase(mut data: &String) {
let data = &data.to_uppercase();
println!("{}", data);
}