rust学习笔记

rust学习笔记

这学期选了一门rust课,今年上半年呢,由PKU精英团队打造的rust内核zroj就要正式上线了,请大家多多支持。

判断语句和循环语句

条件不用加括号,形式和python差不多是for x in ...

没有range,可以用 0..5 表示[0,5)

基础类型 Fundamental Types

定宽数字类型

u8~u128 : 无符号整数

i8~i128 : 有符号整数

f32~f64 : 浮点数

表示一个数可以加后缀: 123i8,也可以类型推断

可以使用下划线对数字进行任意分组

使用as来进行类型转换:

assert_eq!( 10_i8 as u16, 10_u16);
assert_eq!( 2525_u16 as i16, 2525_i16); 
assert_eq!( -1_i8 as u8, 255_u8); //overflow

在debug模式下整数溢出会panic,release模式则不会。

可以使用wrapping operations进行合法的溢出操作

fn main() {
 assert_eq!(100_u16.wrapping_mul(200), 20000); 
}

一些特殊值:

f64::MAX
f64::MIN
f64::INFINITY //inf
f64::NEG_INFINITY
f64::NAN

在f64::const 里有一些常数

打印方法:

println!("{:.20}", PI); // 输出20位

size_of : 获得类型宽度

char

和c++一样是4字节

把u32值转换为char值:std::char::from_u32

tuple

 let t = (1, false, 32.01); 
 // t1是一个元组类型的变量;t1的准确类型是(i64, bool, f32)
 let t1:(i64, bool, f32) = (t.0, t.1, t.2); 
 // t.0, t.1, t.2: 访问元组t中的第1, 第2, 第3个值

无返回值的函数返回零元组

指针类型 pointer types

引用 Reference

在前面加上&,表示内存地址

// 变量value的类型: i32
 let value: i32 = 123;
 // &value: 一个引用类型的值
 // 变量refer的类型: &i32
 let refer = &value;

去引用:加上*,读取该地址的值

只读引用:ref = &value 不能修改*ref

可变引用:ref = &mut value 可以修改*ref

Box

box把值存放在堆(heap)中

栈:程序的工作现场,空间有限但访问效率高

堆:一个仓库,空间大但访问效率较低

fn main() {
    let t = 2022;
    let b = Box::new(t);
    let mut c: Box<i32> = Box::new(t);
    *c = 2023;
    // print b's value
    println!("{:p}", b); // 0x*******
   
    // print b's pointed value
    println!("{}", b); //2022
    // print c's pointed value
    println!("{}", c); //2023
}

Box::new(value) :申请一个地址

内存管理

一个程序至少包含一个进程,一个进程包含多个线程

每一个线程具有自己的一个栈空间,

一个进程的所有线程,共享一个堆空间

数组与vector

array类型:[T; N] (定长)

vector类型:[Vec]

slice切片:&[T] &mut[T]

v.len():长度

以下标访问:v[i],从0开始

输出数组:println!("{:?}",v);

array

rust声明数组必须要初始化:

let a = [1,2,3,4] 
let a = [0; 100] //(100个0)

vector

声明:

let (mut) v = vec![1,2,3,4]
v.insert(position,value)
v.remove(position)
v.push()
v.pop()

这里内部实现是没有平衡树的,时间复杂度较高。

内存包含一堆指针,一个len,一个capacity

slice

fn main() {
 let a: [u16; 4] = [0, 1, 2, 3];
 let v: Vec<u16> = vec![0, 1, 2, 3, 4];
 // sa 是一个类型为 &[u16] 的 slice
 // 包含数组 a 中位置区间[0, 2)上的元素
 let sa: &[u16] = &a[0..2];
 // sa 是一个类型为 &[u16] 的 slice
 // 包含向量 v 中位置区间[1, 4)上的元素
 let sv: &[u16] = &v[1..4];
 println!("{:?}", sa); //=> [0, 1]
 println!("{:?}", sv); //=> [1, 2, 3]
}

当在array或vector上调用slice上的方法时,编译器会自动把array或vector转换为slice:如reverse()和sort()

string

同样使用反斜杠转义,但换行可以直接换行(编辑器里)

raw string

不进行任何转义

let raw_string= r"C:\Program Files\path\to\file";

如果想加入双引号,则加上三个#表示开头和结束

let raw_string= r###""C:\Program Files\path\to\file""###;

string 和 &str

&str = string slice

使用 "Hello".to_string(); 和 String::from("World"); 创建string

&str的len()返回字节数,使用.chars().count()返回字符数量

format!()

和println!相同,返回一个String值

 let a1 = format!("test");
 let a2 = format!("hello {}", "world!");
 let a3 = format!("x = {x}, y = {y}", y = 10, x = 30);
 println!("{}", a1); //=> test
 println!("{}", a2); //=> hello world!
 println!("{}", a3); //=> x = 30, y = 10

.concat

就是concat

.join

concat中间加一个分隔符(放在第二个参数)

mutable String 和 mutable &str

除了vector的method,还有push_str等等method

但是不能通过integer下标改变

其他一些常用方法

fn main() {
    println!("{}", "Hello, world!".contains("world")); //=> true
    println!("{}", "Hello, world!".replace("world", "dog")); //=> Hello, dog!
    println!("{}", " Hello \n ".trim() == "Hello"); //=> true(去除首尾空白)
    for word in "Hello world and dog".split(" ") {
        println!("{}", word); //=> Hello
    }                         //=> world
}                             //=> and
                              //=> dog

type关键字

type Bytes = Vec;

相当于c++里的typedef

struct 和 enum

struct

语法:

struct Image {
	size: (uszie, usize),
    pixels: Vec<u32>
}
let image = Image {
 pixels: vec![0; width * height],
 size: (width, height)
};

在struct上附着/关联方法

使用impl关键字,还有&self关键字(跟python差不多)

注意加上函数返回值类型

enum

和haskell很像,不用给出值,在内存中被表示为一个整数

enum Ordering {
 Less,
 Equal,
 Greater
}

也可以带参数:

enum Color {
	RGB(u8, u8, u8),
	Gray(u8)
}
let a = Color::RGB(63, 127, 255);
let b = Color::RGB(63, 63, 63);
let c = Color::Gray(127);

在enum上附着/关联方法

impl Ordering {
    fn is_eq(self) -> bool {
        if self == Ordering::Equal {
            true
        } else {
            false
        }
    }
}

使用match关键字:

impl Color {
    fn is_gray(&self) -> bool {
        match self {
            Color::Gray(_) => true,
            Color::RGB(a, b, c) =>
            if a == b && b == c {
                true
            } else {
                false
            }
        }
    }
}

std::option::Option

这不是我们haskell的Maybe吗!

pub enum Option<T>{
    None,
    Some(T),
}
posted @ 2023-02-20 22:30  lcyfrog  阅读(116)  评论(0编辑  收藏  举报