rust学习笔记之小练习:原生类型、常见集合类型、迭代器、结构体

原生类型

let char= 'C';
println!("{} is_alphabetic: {}",char,char.is_alphabetic()); // C is_alphabetic: true
println!("{} is_numeric: {}",char,char.is_numeric()); // C is_numeric: false
let char='中';
println!("{} is_alphabetic: {}",char,char.is_alphabetic()); // 中 is_alphabetic: true
println!("{} is_numeric: {}",char,char.is_numeric()); // 中 is_numeric: false

let arr = [1;100];
println!("len:{},arr[1]:{}",arr.len(),arr[1]); // len:100,arr[1]:1

let a = [1, 2, 3, 4, 5];
let nice_slice = &a[1..4];
println!("{:?}",nice_slice); // [2, 3, 4]

let cat = ("Furry McFurson", 3.5);
let (name,age) = cat;
println!("name:{},age:{}", name, age); // name:Furry McFurson,age:3.5
println!("name:{},age:{}", cat.0, cat.1); // name:Furry McFurson,age:3.5

String

fn main() {
    let answer = favorite_color();
    println!("favorite color is {}", answer); // favorite color is blue
    
    let word = String::from("green");
    println!("{},{}", word,is_a_color_word(&word)); // green,true
    
    assert_eq!(trim_me("Hello!     "), "Hello!");
    assert_eq!(trim_me("  What's up!"), "What's up!");
    assert_eq!(trim_me("   Hola!  "), "Hola!");
    
    assert_eq!(compose_me("Hello"), "Hello world!");
    assert_eq!(compose_me("Goodbye"), "Goodbye world!");
    
    assert_eq!(replace_me("I think cars are cool"), "I think balloons are cool");
    assert_eq!(replace_me("I love to look at cars"), "I love to look at balloons");
    
    string_slice("blue");
    string("red".to_string());
    string(String::from("hi"));
    string("rust is fun!".to_owned());
    string("nice weather".into());
    string(format!("Interpolation {}", "Station"));
    string_slice(&String::from("abc")[0..1]);
    string_slice("  hello there ".trim());
    string("Happy Monday!".to_string().replace("Mon", "Tues"));
    string("mY sHiFt KeY iS sTiCkY".to_lowercase());
}

fn favorite_color() -> String {
    String::from("blue")
}

fn is_a_color_word(attempt: &str) -> bool {
    attempt == "green" || attempt == "blue" || attempt == "red"
}

fn trim_me(input: &str) -> String {
    input.trim().to_string()
}

fn compose_me(input: &str) -> String {
    let mut s = String::from(input);
    s.push_str(" world!");
    s
}

fn replace_me(input: &str) -> String {
    input.to_string().replace("cars","balloons")
}

fn string_slice(arg: &str) {
    println!("{}", arg);
}

fn string(arg: String) {
    println!("{}", arg);
}

vector

fn main(){
    let (a, v) = array_and_vec();
    println!("a:{:?},v:{:?}",a,v); // a:[10, 20, 30, 40],v:[10, 20, 30, 40]
    
    let v: Vec<i32> = (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::<Vec<i32>>());
    let ans = vec_map(&v);
    assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
}

fn array_and_vec() -> ([i32; 4], Vec<i32>) {
    let a = [10, 20, 30, 40]; 
    let v = Vec::from(a);  // 从数组创建 Vector
    (a, v)
}


fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for i in v.iter_mut() {
       *i *=2 ;
    }
    v
}

fn vec_map(v: &Vec<i32>) -> Vec<i32> {
    v.iter().map(|num| {
        *num * 2
    }).collect()
}

HashMap

use std::collections::HashMap;

#[derive(Hash, PartialEq, Eq)]
enum Fruit {
    Apple,
    Banana,
    Mango,
    Lychee,
    Pineapple,
}

struct Team {
    name: String,
    goals_scored: u8,
    goals_conceded: u8,
}

fn main(){
    let basket = fruit_basket();
    assert!(basket.len() >= 3);
    assert!(basket.values().sum::<u32>() >= 5);
    
    let mut basket = get_fruit_basket();
    refresh_fruit_basket(&mut basket);
    assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4);
    assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2);
    assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5);
    assert!(basket.len() >= 5);
    assert!(basket.values().sum::<u32>() > 11);    
  
    let scores = build_scores_table(get_results());
    let mut keys: Vec<&String> = scores.keys().collect();
    keys.sort();
    assert_eq!(keys,vec!["England", "France", "Germany", "Italy", "Poland", "Spain"]);
    let team = scores.get("England").unwrap();
    assert_eq!(team.goals_scored, 5);
    assert_eq!(team.goals_conceded, 4);
    let team = scores.get("Spain").unwrap();
    assert_eq!(team.goals_scored, 0);
    assert_eq!(team.goals_conceded, 2);
}

fn fruit_basket() -> HashMap<String, u32> {
    let mut basket = HashMap::<String, u32>::new();
    basket.insert(String::from("banana"), 2);
    basket.insert(String::from("apple"), 2);
    basket.insert(String::from("pear"), 2);
    basket
}

fn get_fruit_basket() -> HashMap<Fruit, u32> {
    let mut basket = HashMap::<Fruit, u32>::new();
    basket.insert(Fruit::Apple, 4);
    basket.insert(Fruit::Mango, 2);
    basket.insert(Fruit::Lychee, 5);
    basket
}

fn refresh_fruit_basket(basket: &mut HashMap<Fruit, u32>) {
    let fruit_kinds = vec![
        Fruit::Apple,
        Fruit::Banana,
        Fruit::Mango,
        Fruit::Lychee,
        Fruit::Pineapple,
    ];

    for fruit in fruit_kinds {
        basket.entry(fruit).or_insert(2); 
    }
}

fn get_results() -> String {
    let results = "".to_string()
        + "England,France,4,2\n"
        + "France,Italy,3,1\n"
        + "Poland,Spain,2,0\n"
        + "Germany,England,2,1\n";
    results
}

fn build_scores_table(results: String) -> HashMap<String, Team> {
    let mut scores: HashMap<String, Team> = HashMap::new();

    for r in results.lines() {
        let v: Vec<&str> = r.split(',').collect();
        let team_1_name = v[0].to_string();
        let team_1_score: u8 = v[2].parse().unwrap();
        let team_2_name = v[1].to_string();
        let team_2_score: u8 = v[3].parse().unwrap();

        let tm = scores.entry(team_1_name.clone()).or_insert(Team{
                name: team_1_name,
                goals_scored: 0,
                goals_conceded:0
            });
        (*tm).goals_scored += team_1_score;
        (*tm).goals_conceded += team_2_score;

        let tm = scores.entry(team_2_name.clone()).or_insert(Team{
                name: team_2_name,
                goals_scored: 0,
                goals_conceded:0
            });
        (*tm).goals_scored += team_2_score;
        (*tm).goals_conceded += team_1_score;
    }
    scores
}

iterators

fn main () {
    let fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
    let mut iterable_fruits = fruits.iter();
    assert_eq!(iterable_fruits.next(), Some(&"banana"));
    assert_eq!(iterable_fruits.next(), Some(&"custard apple"));     
    assert_eq!(iterable_fruits.next(), Some(&"avocado"));
    assert_eq!(iterable_fruits.next(), Some(&"peach"));    
    assert_eq!(iterable_fruits.next(), Some(&"raspberry"));
    assert_eq!(iterable_fruits.next(), None);    
    
    assert_eq!(capitalize_first("hello"), "Hello");
    assert_eq!(capitalize_first(""), "");
    
    let words = vec!["hello", "world"];
    assert_eq!(capitalize_words_vector(&words), ["Hello", "World"]);
    
    let words = vec!["hello", " ", "world"];
    assert_eq!(capitalize_words_string(&words), "Hello World");
}

pub fn capitalize_first(input: &str) -> String {
    let mut chars = input.chars();
    match chars.next() {
        None => String::new(),
        Some(first) => {
            // 'h'.to_uppercase()方法返回迭代器,collect()方法主要用于将迭代器转换为集合类型
            let mut result = first.to_uppercase().collect::<String>();
            result.extend(chars);
            result
        }
    }
}

pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
    words.iter().map(|w| capitalize_first(w)).collect::<Vec<String>>()
}

pub fn capitalize_words_string(words: &[&str]) -> String {
    words.iter().map(|w| capitalize_first(w)).collect::<String>()
}

迭代器练习2

#[derive(Debug, PartialEq, Eq)]
pub enum DivisionError {
    NotDivisible(NotDivisibleError),
    DivideByZero,
}

#[derive(Debug, PartialEq, Eq)]
pub struct NotDivisibleError {
    dividend: i32,
    divisor: i32,
}

fn main(){
    assert_eq!(divide(81, 9), Ok(9));
    assert_eq!(divide(81, 6),Err(DivisionError::NotDivisible(NotDivisibleError {dividend: 81,divisor: 6})));
    assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
    assert_eq!(divide(0, 81), Ok(0));
 
    assert_eq!(format!("{:?}", result_with_list()), "Ok([1, 11, 1426, 3])");

    assert_eq!(format!("{:?}", list_of_results()),"[Ok(1), Ok(11), Ok(1426), Ok(3)]");
}

pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
    if b==0 {
        Err(DivisionError::DivideByZero)
    }else {
        if a % b==0 {
            Ok(a/b)
        }else{
            Err(DivisionError::NotDivisible(NotDivisibleError{dividend:a,divisor:b}))
        }
    }
}

fn result_with_list() -> Result<Vec<i32>,DivisionError> {
    let numbers = vec![27, 297, 38502, 81];
    let division_results:Result<Vec<i32>,DivisionError> = numbers.into_iter().map(|n| divide(n, 27)).collect();
    division_results
}

fn list_of_results() -> Vec<Result<i32, DivisionError>> {
    let numbers = vec![27, 297, 38502, 81];
    let division_results:Vec<Result<i32, DivisionError>> =numbers.into_iter().map(|n| divide(n, 27)).collect();
    division_results 
}

迭代器练习3

use std::collections::HashMap;

#[derive(Clone, Copy, PartialEq, Eq)]
enum Progress {
    None,
    Some,
    Complete,
}

fn main(){
    assert_eq!(1, factorial(0));
    assert_eq!(1, factorial(1));
    assert_eq!(2, factorial(2));
    assert_eq!(24, factorial(4));
    
    let map = get_map();
    assert_eq!(3, count_iterator(&map, Progress::Complete));
    assert_eq!(count_for(&map, Progress::Complete),count_iterator(&map, Progress::Complete));

    let collection = get_vec_map();
    assert_eq!(6,count_collection_iterator(&collection, Progress::Complete));
    assert_eq!(count_collection_for(&collection, Progress::Complete),count_collection_iterator(&collection, Progress::Complete));
}

pub fn factorial(num: u64) -> u64 {
    if num<=1{
        1
    }else{
        (1..(num+1)).product()
    }
}

fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
    let mut count = 0;
    for val in map.values() {
        if val == &value {
            count += 1;
        }
    }
    count
}

fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
    map.values().filter(|&&v| v==value).map(|&_| 1).sum()
}

fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
    let mut count = 0;
    for map in collection {
        for val in map.values() {
            if val == &value {
                count += 1;
            }
        }
    }
    count
}

fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
    collection.iter().map(|map| map.values().filter(|&&v| v==value).map(|&_| 1).sum::<usize>()).sum::<usize>()
}

fn get_map() -> HashMap<String, Progress> {
    let mut map = HashMap::new();
    map.insert(String::from("variables1"), Progress::Complete);
    map.insert(String::from("functions1"), Progress::Complete);
    map.insert(String::from("hashmap1"), Progress::Complete);
    map.insert(String::from("arc1"), Progress::Some);
    map.insert(String::from("as_ref_mut"), Progress::None);
    map.insert(String::from("from_str"), Progress::None);

    map
}

fn get_vec_map() -> Vec<HashMap<String, Progress>> {
    let map = get_map();

    let mut other = HashMap::new();
    other.insert(String::from("variables2"), Progress::Complete);
    other.insert(String::from("functions2"), Progress::Complete);
    other.insert(String::from("if1"), Progress::Complete);
    other.insert(String::from("from_into"), Progress::None);
    other.insert(String::from("try_from_into"), Progress::None);

    vec![map, other]
}

结构体

struct ColorClassicStruct {
   red:u8,
   green:u8,
   blue:u8
}

struct ColorTupleStruct(u8,u8,u8);

#[derive(Debug)]
struct UnitLikeStruct;

#[derive(Debug)]
struct Order {
    name: String,
    year: u32,
    made_by_phone: bool,
    made_by_mobile: bool,
    made_by_email: bool,
    item_number: u32,
    count: u32,
}

fn create_order_template() -> Order {
    Order {
        name: String::from("Bob"),
        year: 2019,
        made_by_phone: false,
        made_by_mobile: false,
        made_by_email: true,
        item_number: 123,
        count: 0,
    }
}

#[derive(Debug)]
struct Package {
    sender_country: String,
    recipient_country: String,
    weight_in_grams: i32,
}

impl Package {
    fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
        if weight_in_grams <= 0 {
            panic!("Can not ship a weightless package.")
        } else {
            Package {
                sender_country,
                recipient_country,
                weight_in_grams,
            }
        }
    }

    fn is_international(&self) -> bool {
        self.sender_country != self.recipient_country
    }

    fn get_fees(&self, cents_per_gram: i32) -> i32 {
        self.weight_in_grams * cents_per_gram
    }
}

fn main(){
    let green =ColorClassicStruct{red:0,green:255,blue:0};
    assert_eq!(green.red, 0);
    assert_eq!(green.green, 255);
    assert_eq!(green.blue, 0);
    
    let green =ColorTupleStruct(0,255,0);
    assert_eq!(green.0, 0);
    assert_eq!(green.1, 255);
    assert_eq!(green.2, 0);
    
    let unit_like_struct = UnitLikeStruct;
    let message = format!("{:?}s are fun!", unit_like_struct);
    assert_eq!(message, "UnitLikeStructs are fun!");
    
    let order_template = create_order_template();
    let your_order =  Order {
        name: String::from("Hacker in Rust"),
        count: 1,
        ..order_template
    };
    assert_eq!(your_order.name, "Hacker in Rust");
    assert_eq!(your_order.year, order_template.year);
    assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
    assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile);
    assert_eq!(your_order.made_by_email, order_template.made_by_email);
    assert_eq!(your_order.item_number, order_template.item_number);
    assert_eq!(your_order.count, 1);
    
    let sender_country = String::from("Spain");
    let recipient_country = String::from("Russia");
    let package = Package::new(sender_country, recipient_country, 1200);
    assert!(package.is_international());
    
    let sender_country = String::from("Canada");
    let recipient_country = sender_country.clone();
    let package = Package::new(sender_country, recipient_country, 1500);
    assert!(!package.is_international());
    let cents_per_gram = 3;
    assert_eq!(package.get_fees(cents_per_gram), 4500);
    assert_eq!(package.get_fees(cents_per_gram * 2), 9000);
}
posted @ 2025-08-08 17:07  carol2014  阅读(7)  评论(0)    收藏  举报