Rust学习

并发

Rust无畏并发:允许编写没有细微BUG的代码,并在不引入新BUG的情况下易于重构

多线程

实现多线程的方式:使用Os的Api创建线程, 1:1模型,2.语言自己实现的线程, M:N模型

Rust标准库仅提供1:1线程模型,通过Thread::spawn创建新线程,参数为闭包(新线程中运行的代码

fn main() {
    let a = || {
        loop {
            println!("我是子进程");
            // 暂停两秒
            thread::sleep(Duration::from_secs(2));
        }
    };
    let son_thread = thread::spawn(a);
    loop {
        println!("我是父进程");
        thread::sleep(Duration::from_secs(1));
    }
    // join干哈的我就不多说了
    son_thread.join();
}
我是父进程
我是子进程
我是父进程
我是父进程

必报的子线程可以贡献同一作用域下的其他线程参数,这是闭包的特性哦应该没有忘记把。但是在多线程中我们还需要Move来传递参数

fn main() {
    let data = String::from("我是主线程数据");
    // let a = move || {
    let a = || {
            println!("获取主线程的数据: {}", data);
    };
    let son_thread = thread::spawn(a);
    son_thread.join();
}
let a = || {
   |             ^^ may outlive borrowed value `data`
8  |             println!("获取主线程的数据: {}", data);
   |                                               ---- `data` is borrowed here

这里的报错的意思指:我们在子线程中调用的这个数据可能在子线程运行完毕之前就被del了,Rust编译器连这都想到了确实很细致。我们如果一定要获得参数的化使用Move 获取此参数的所有权即可

消息传递

消息传递是一种很流行的保证安全并发的线程通讯技术。线程彼此之间通过发送消息完成通讯。可以理解为Python中的携程

Rust 使用Channel(标准库提供)实现进程通讯。Channel包含发送端域接收单,调用发送端的方法就是发送数据,接收端会检查和接受收到的数据。如果发送,接受任意一端被丢弃,Channel就关闭了

使用mpsc::channel创建Channel (多个生产者,一个消费者), 返回一个元组,一个发送端,一个接收端。

fn main() {
    let (sender,receiver) = mpsc::channel();
    let a = move || {
        loop {
            //返回Result<T,E>, 有问题就甩Err
            sender.send(String::from("Hello"));
            // 这里如果上面发送的是变量的化,那所有权已经在receiver手里了
            println!("获取主线程发送数据: Hello");
            thread::sleep(Duration::from_secs(1));
        }
    };
    let son_thread = thread::spawn(a);
    loop {
        // 阻塞当前线程知道Channel中有值送到, 发送端关闭则返回错误
        let data = receiver.recv().unwrap();
        println!("收到数据: {}",data);
    }
    son_thread.join();
}
收到数据: Hello
获取主线程发送数据: Hello
获取主线程发送数据: Hello
收到数据: Hello

对于发送者,我们可以使用克隆创建多个发送者,毕竟是多生产者单消费者

共享状态的并发

这一节讲的就是锁,利用Mutex<T,E> 进行上锁,并使用ARC<T>使其s拥有多重所有权.我的评价是不如通讯、不如携程。

ooj 面向对象

面向对象不是简单的有类有函数就OJBK了, 面向对象三大特性最少要保证吧:封装,继承,堕胎。关于Rust的面向对象特性其实是一个比较矛盾的存在。

  • 封装:调用对象外部的代码无法直接访问对象内部的实现细节,唯一与对象交互的方法就是公开的API. Rust中我们引用的时候不是只能引用被pub修饰的方法,或者说mod么,在这种情况下我们可以认为Rust是具有封装特性的
  • Rust中没有继承的概念。继承的目的主要是代码复用较少代码量, 但是Rust未见过啥结构体,枚举类型继承的情况。Rust本身虽然没有复用,但是我们可以使用trait定义加上泛形试下代码的共享 。同时我们可以覆盖已经实现的trait, 只能说实现了一定程度的继承。
  • 多态:Rust中使用泛形和trait约束限定多态。

trait对象其实更多像接口或抽象类定义,在我们上一张学了Box之后就可以采用Box进行泛化了。BOx进行泛化保证同一个Vec中可以存储不同类型, 这种派发与普通的trait泛形约束相比较属于动态派发,无法在编译时确定类型。对于这种trait,Rust限定了两条法则保证安全

  1. 方法的返回类型是Self
  2. 方法中不包含任何泛形类型参数
// 一个泛形的例子
use crate::type2::Name2;

trait whoami{
    fn print_my_type(&self);
}
struct  type1{
    Name1:String,
}

impl whoami for type1 {
    fn print_my_type(&self) {
        println!("I'm type1");
    }
}
enum type2{
    Name2(Vec<String>),
}

impl whoami for type2 {
    fn print_my_type(&self) {
        println!("I'm type 2")
    }
}

struct type_done_whoami_trait{
    // 完成了vec的都可以放到type_vec中
    type_vec:Vec<Box<dyn whoami>>,
}

impl type_done_whoami_trait{
    fn new() -> type_done_whoami_trait{
        let a = type1{ Name1: String::new()};
        let c = type1{ Name1: String::new()};
        let b = type2::Name2(vec![String::new()]);
        type_done_whoami_trait {
            type_vec: vec![Box::new(a),Box::new(b),Box::new(c)]
        }
    }
}

fn main() {
    let c = type_done_whoami_trait::new();
    for p in c.type_vec{
        // 这里直接 p.print_my_type()也是可以的
        (*p).print_my_type();
    }
}

经典面向对象的模式不适合Rust,使用需谨慎哦

学习 Rust 是一个非常有价值的选择,因为它是一种系统级编程语言,强调安全、性能和并发。它通过其独特的所有权(ownership)和借用(borrowing)机制,在不依赖垃圾回收器的情况下保证内存安全。 以下是一个简单的 Rust 程序示例,展示了如何打印 "Hello, world!": ```rust // main.rs fn main() { println!("Hello, world!"); } ``` ### 解释: - `fn main()` 是程序的入口点。 - `println!` 是一个宏,用于打印文本到控制台,并自动换行。 --- ## 编译与运行 1. 安装 Rust:使用 [https://rust-lang.org](https://rust-lang.org) 提供的安装工具 rustup。 2. 创建一个文件 `main.rs`。 3. 使用 `rustc` 编译器编译代码: ```bash rustc main.rs ``` 4. 运行生成的可执行文件: ```bash ./main ``` --- ## 变量、数据类型与函数 Rust 强调安全性,变量默认是不可变的(immutable),需要加上 `mut` 才能修改。 ```rust fn main() { let mut x = 5; println!("The value of x is: {}", x); x = 6; println!("The value of x is: {}", x); let y: i32 = 32; // 显式声明类型 println!("The value of y is: {}", y); } ``` ### 函数定义 ```rust fn add(a: i32, b: i32) -> i32 { a + b } fn main() { let result = add(3, 4); println!("Result is: {}", result); } ``` --- ## 控制流:if 表达式和循环 ```rust fn main() { let number = 6; if number % 2 == 0 { println!("Even"); } else { println!("Odd"); } // loop 循环 let mut counter = 0; loop { println!("Counter: {}", counter); counter += 1; if counter == 3 { break; } } // while 循环 while counter < 5 { println!("Counter in while: {}", counter); counter += 1; } // for 循环 for i in 0..3 { println!("For loop: {}", i); } } ``` --- ## 所有权(Ownership)与引用(Borrowing) 这是 Rust 的核心概念之一。 ```rust fn main() { let s1 = String::from("hello"); let s2 = s1; // s1 不再有效 // println!("{}", s1); // ❌ 报错!因为 s1 已经被移动了 let s3 = s2.clone(); // 深拷贝 println!("s2: {}, s3: {}", s2, s3); } ``` 如果你不想转移所有权,可以使用引用: ```rust fn print_length(s: &String) { // 借用 println!("Length is: {}", s.len()); } // s 不拥有所有权,所以不会释放内存 fn main() { let s = String::from("Rust"); print_length(&s); println!("{}", s); // ✅ 仍然可用 } ``` --- ## 结构体(Struct) ```rust struct User { username: String, email: String, sign_in_count: u64, active: bool, } fn main() { let user1 = User { email: String::from("user@example.com"), username: String::from("user1"), active: true, sign_in_count: 1, }; println!("User email: {}", user1.email); } ``` --- ## 枚举(Enum) ```rust enum IpAddrKind { V4, V6, } fn main() { let four = IpAddrKind::V4; let six = IpAddrKind::V6; } ``` 还可以为枚举附加数据: ```rust enum IpAddr { V4(u8, u8, u8, u8), V6(String), } fn main() { let home = IpAddr::V4(127, 0, 0, 1); let loopback = IpAddr::V6(String::from("::1")); } ``` --- ## Option 枚举处理可能缺失的值 Rust 中没有 null,而是用 `Option<T>` 来表示可能存在或不存在的值。 ```rust fn main() { let some_number = Some(5); let absent_number: Option<i32> = None; match some_number { Some(n) => println!("Got a number: {}", n), None => println!("No number found"), } } ``` --- ## 错误处理 Rust 使用 `Result` 类型来处理可能出错的操作。 ```rust use std::fs::File; use std::io::Read; fn read_file_contents() -> Result<String, std::io::Error> { let mut file = File::open("example.txt")?; let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents) } fn main() { match read_file_contents() { Ok(contents) => println!("File contents:\n{}", contents), Err(e) => println!("Error reading file: {}", e), } } ``` --- ## 包管理器 Cargo Cargo 是 Rust 的构建系统和包管理器。创建项目: ```bash cargo new hello_rust cd hello_rust cargo build cargo run ``` --- ## 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值