rust 入门遇到的问题

108 阅读5分钟

1. 在例子中得到的问题并找到答案的

use std::io;
use rand::Rng;
use std::cmp::Ordering;

fn main() {
    println!("Guess the number");

    // 这些api 文档哪里看?->  cargo doc --open
    let secret_number = rand::thread_rng().gen_range(1..=101);
    // println!("The secret_number is: {}", secret_number);

    loop {
        println!("Please input your Guess.");
        let mut guess = String::new();
        io::stdin().read_line(&mut guess).expect("Failed to read line");

        println!("You Guessed: {}",guess);

       
        // 为何可以重复声明? -> shadow  -> 类型转换
        let guess:i32 = match guess.trim().parse(){
            Ok(num) => num,
            Err(_) => continue,
        };

        // 类型如何转换 ?
        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too Small"),
            Ordering::Greater => println!("Too Big"),
            Ordering::Equal => {
                    println!("You win");
                    break;
                },
        }
    }
   
}

[dependencies]
#### 如何更新依赖? ->,cargo update
eframe = "0.26.2"
rand = "0.8.3"

2. 在例子中得到的问题目前还没找到答案的


fn main() {
       const THREE_HOURE_IN_SECONDS:u32 = 60 * 60 * 3;
       println!("THIS is :{}",THREE_HOURE_IN_SECONDS);
       // -5/3 如何表示?  
       let guess: f32 = -3.0 / 2.0;
       println!("GUESS: {}", guess);
       let tup = (27,"ABC", 'B');
       println!("tup {},{},{}", tup.0,tup.1,tup.2);
    
       let arr = [10;10];
       println!("arr {}",arr[9]);
       
       loop_fn();
       let x = fibonacci(5);
       println!("fibonacci {}",x);
    
       let u = fibonacci_two(5);
       let u = format!("{:?}", u);
       println!("fibonacci {}", u);
}

fn loop_fn() {
    let mut count = 0;
    let t = 't';
    // 单引号为啥正确? 
    'counting_up: loop {
        println!("count = {}", count);
        let mut remaining = 10;
        loop {
            println!("remaining = {}", remaining);
            if remaining == 9 {
                break;
            } else if count == 2 {
                break 'counting_up;
            }

            remaining -= 1;
        }
        count += 1;
    }
    println!("End count = {}", count);
}
    


fn fibonacci(n:usize) -> usize {
    match n{
        1 => 0,
        2 => 1,
        _ => fibonacci(n-1) + fibonacci(n-2)
    }
}
// Vec 是个啥?
fn fibonacci_two(n: usize) -> Vec<usize> {
    if n <= 0 {
        return vec![];
    } else if n == 1 {
        return vec![0];
    } else if n == 2 {
        return vec![0, 1];
    } else {
        let mut fib_sequence = vec![0, 1];
        for _ in 2..n {
            fib_sequence.push(fib_sequence[fib_sequence.len() - 1] + fib_sequence[fib_sequence.len() - 2]);
        }
        return fib_sequence;
    }
}

2.1答案出处

3. 优势对比(概念)

use std::fmt::Debug;

fn main() {
    // 所有权规则(70-95)
    // Rust 中的每一个值都有一个被称其为所有者(owner)的变量
    // 值在任一时刻有且只有一个所有者
    // 当所有者(变量)离开作用域,这个值将被丢弃

    // 1.Rust 有什么优势?
        // 1. 内存方面
        // 堆/栈
        // 栈和堆都是代码在运行时可提供使用的内存
        // 栈 LIFO 占用已知固定大小
        // 堆 编译时大小未知或大小可能改化的数据 访问实际数据时必需访问指针
        // 访问堆上的数据比访问栈上的数据慢 因为必需通过指针来访问 堆必需通过指针来访问

        // 2. 有CG(垃圾回收) 会存在的问题 1.忘记收回浪费内存 2.过早回收会出来无效变量 3. 重复回收 内存二次释放 两次释放(相同)内存会导致内存污染 引发bug 
        // -> Rust 采取的解决策略是 内存在拥有它的变量离开作用域后就被自动释放 -> 结尾处自动调用drop函数释放内存
    // 2. 数据竞争(data race)
        // 1.两个或更多指针访问同一数据 2.至少有一个指针用来写入数据 3. 没有同步数据访问的机制
        // 3个行为同时发生才会造成数据竞争
        // -> Rust 避免了这种情况的发生,它甚至不会编译存在数据竞争的代码
    // 3. 悬垂引用
        // -> Rust 中编译器确保引用永远不会变成悬垂状态: 当你拥有一些数据的引用 编译器确保数据不会在其引用之前离开作用域
        
    // 变量与数据的交互方式
    // 移动(move) 深copy 浅copy 
    // 克隆(clone) 深度复制堆中的数据

    // 所有权函数 引用/借用 &
    // 引用的规则
    // 1.在任意给定时间,要么只能有一个可变引用,要么只能有多个不可变引用
    // 2.引用必须总是有效的


    let s = String::from("hello world");
    let a = &s[..];
    let b = &s[..5];
    let c = &s[6..];
    let d = &s[0..5];
    println!("{},{},{},{}",a,b,c,d);

    let t = [1,3,5,7,8];
    let e = &t[..2];

    println!("{:?}",e);


    // 结构体如何输出到控制台? -> 通过trait实现 105 
    let user1 = User {
        active: true,
        user_name: String::from("wang er"),
        email: String::from("123@qq.com"),
        sign_in_count: 1
    };

    println!("{:?}",user1);

    let color = Color(0,0,0);
    let point = Point(0,0,0);
    println!("{:?}",color);
    println!("{:?}",point)
}

#[derive(Debug)]
struct Color(i32,i32,i32);
#[derive(Debug)]
struct Point(i32,i32,i32);

// 实现输出
#[derive(Debug)]
struct User {
    active: bool,
    user_name: String,
    email: String,
    sign_in_count: u64
}

// 实现输出
impl Debug for User {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("User")
            .field("active", &self.active)
            .field("username", &self.username)
            .field("email", &self.email)
            .field("sign_in_count", &self.sign_in_count)
            .finish()
    }
}

4. 功能实现 使用合理手段优化

fn main() {
    let weight = 30;
    let height = 50;
    let rect = (30,50);

    let rect = Rectangle{
        weight:30,
        height:50,
    };
    println!("{:#?}", rect);
    
    println!(
        "The area of the rectangle {} square pixels",
        // area(weight,height)
        // area(&rect),
        rect.area()
    )
    // 打印调试
    dbg!(&rect);
    
}

// 两个参数没有关联性(103)
fn area(weight:u32,height:u32) -> u32 {
    weight * height
}
// 使用元祖结构没有元素名称(104)
fn area(dimensions:(u32,u32)) -> u32 {
    dimensions.0 * dimensions.1
}
// 使用结构体明确意图清晰明了
fn area(rectangle: &Rectangle) -> u32 {
    rectangle.weight * rectangle.height
}

#[derive(Debug)]
struct Rectangle {
    weight: u32,
    height: u32
}
// 使用方法代替函数
impl Rectangle {
    fn area(&self) -> u32 {
        self.weight * self.height
    }
}

最后

时间过得快,慢慢生长,慢慢发芽,慢慢去除前端的标签。以前学习前端的时候也会有很多问题,但是都是东记一点,西记一点,后面好多就找不见了,现在有时间有闲心在尝试一个学习一个小玩意就单纯的记录自己遇到的问题,有些能找到答案的就-> 标记出来,目前找不答案的也记录在这里后面找到了,再来补上答案。毕竟生活不是项目,暂时没有答案就暂时没有呗。