rust学习笔记

2025-05-11

关于rust的随笔

begin

哈… 上次写笔记还是前两个月,都都忘得差不多了, 学rust有一段时间了,特来总结一下吧,也就是一个随笔 随便写写

学rust有用吗,也许吧,我学这门语言只是为了开心而已,可是开心能当饭吃吗,诗歌与远方,哎…

just for fun 也许就是我的墓志铭了

ferris

基础的语法以及数据类型

数据类型

老三样:整型,布尔,浮点,有个特殊的地方是 字符和字符串,rust的字符串也就是String 这个数据类型有一些特殊的地方,是关于借用问题

rust的数据定义关键字 let 比如:

 let a:i32= 10;//整型,有i32,i64都有
 let b:&str="hello world";//字符串切片
 let c:String="hello world".to_string();//字符串,借用问题需要好好牢记,待会儿看看
 let d:f32=1.22;//浮点,有f32,f64等等数据类型
 //一些复杂类型
 //数组
 let a[i32,4]=[10;1];//初始化一个数组,这样写方便点
 //一般用vec用的多一些
 let v=vec![1,2,3,4];//用vec宏
 //也可以用Vec::new()方法
 let v:Vec<_>=Vec::new();//不过需要声明类型
 //结构体,跟c差不多
 //先定义后在定义变量
 pub struct Person{
    name:String,
    age:i32,
 }
 //有一个特殊的地方是,rust的面对对象方面,new方法需要自己定义,与c,c++不同的是成员函数的实现方式在rust中是 implment 是impl关键字
 //譬如
 impl Person{
    pub fn new(name:&str,age:i32)->Self{
        Self{
            name:name.to_string(),
            age:age
        }
    }
 }
 //在外部定义,里边可以包含多个参数,偶对了,
 //强烈推荐rust的开发工具,rust-analyzer,真的好用,要是优化好一些就好了,占用内存太大了

关于字符串的和字符串切片

rust有个所有权操作,这个咋说呢,让人又爱有恨 在一定程度上避免的一些安内存安全问题,而且无gc 既安全又高效,感觉的确不错,我先在还是小白,了解还不是特别多.

他这个所有权体现在哪里呢,比如说:

{
    let s = String::from("hello"); // s 进入作用域
} // s 离开作用域,分配给它的内存被释放

一些含有所有权的数据类型: String 可以修改长度的字符串类型,其内容存储在堆上 **Vec** 动态数组,可以在运行时增长和缩小,其元素存储在堆上 **自定义结构体Structs** 当结构体包含堆分配的数据成员(如 String 或 Vec)时,该结构体实例就拥有这些数据的所有权

枚举 与结构体类似,如果枚举的某个变体包含堆分配的数据,则该枚举实例将拥有这些数据的所有权 智能指针 Box:用于在堆上分配值 Rc:提供引用计数的功能,允许数据有多个所有者 Arc:类似于 Rc,但线程安全

不过有个借用机制,可以类比c语言中的引用 有引用和可变引用,忘记说了

mut关键字用来定义一个值可以被修改

let s = String::from("hello");
let len = calculate_length(&s); // &s 是 s 的引用,不拥有 s 的所有权


let mut s = String::from("hello");
change(&mut s); // &mut s 是 s 的可变引用

可变引用的话,一个作用域里边只能有一个

我🌿,写rust就是跟编译器做斗争啊,有的时候编译器死活不通过,其实也还行吧,c语言编译通过的时候有时候会崩溃,这个也许相比c语言要好一些

数据类型转换

一些关于数值类型的转换用到as关键字

   let integer=33;
   let float=integer as f32;
   let float2=3.12;
   let integer2=float2 as f64;

数字和字符,字符串之间的转换

 //数字转字符串
    let str = integer.to_string();
    let a = "22";
    //字符串转换成数字
    let b = a.parse::<i32>().unwrap();
    
 //数字转字符
    let c=3;
    let c_chr=char::from_digit(c, 10).unwrap();

    //字符转换成数字
    let d_str='1';
    let d=d_str.to_digit(10);

有的需要用到from和into两个trait这个之后再做笔记

关于trait

//trait类似于c++中的虚函数或者java的interface接口,我是这么认为的
//比如说
fn main() {
    println!("Hello, world!");

    let p1 = Person::new("aaa", 32);
    let d1 = Dog::new("bb", 3);
    d1.info();
    p1.info();
}
// trait支持默认实现
pub trait Info {
    fn info(&self);
}
pub struct Person {
    pub name: String,
    pub age: i32,
}
pub struct Dog {
    pub name: String,
    pub age: i32,
}
impl Dog {
    fn new(name: &str, age: i32) -> Self {
        Self {
            name: name.to_string(),
            age: age,
        }
    }
}
impl Person {
    fn new(name: &str, age: i32) -> Self {
        Self {
            name: name.to_string(),
            age: age,
        }
    }
}

impl Info for Person {
    fn info(&self) {
        println!("person_name:{}\n person_age:{}", self.name, self.age);
    }
}
impl Info for Dog {
    fn info(&self) {
        println!(" dog_type:{}\n dog_age:{}", self.name, self.age);
    }
}

//trait结合泛型能实现更强大的功能

泛型

泛型这个玩意,嘶…我到现在也没有学明白,太菜了 之前学了点c++的模板,感觉似乎rust的泛型类似于模板,莫非?rust就是精简版的c++?哈哈哈也许吧..

泛型的声明方式:


fn function_name<T>(param: T) {
    // 函数体
}



//这样的方式
fn same<T>(item: T) -> T {
    item
}

fn main() {
    let a = same(1);
    let b = same("hello");
}

//结构体

struct Point<T> {
    x: T,
    y: T,
}

fn some_function<T: Display>(item: T) {
    println!("{}", item);
}

// 假设我们有一个泛型函数,它需要比较两个值的大小。为了做到这一点,我们需要确保传入的类型实现了 PartialOrd 特性,因为这个特性提供了比较运算符(如 <, >, <=, >=)所需的函数。


fn find_max<T: PartialOrd>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

fn main() {
    let max_int = find_max(10, 20);
    println!("Max int: {}", max_int);

    let max_float = find_max(10.5, 20.1);
    println!("Max float: {}", max_float);
}