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),
}