Rust精简核心笔记:第一波,深入浅出语法精华

上一篇介绍了Rust 2024年目前的发展情况 , 后边几天也争取把相关Rust的学习笔记和快速入门进行介绍,帮助感兴趣的快速上手Rust,今天先介绍整理的精简核心语法第一波。

Rust精简笔记(一)

  •  适用于对Rust语言感兴趣,了解Rust,并想快速学习和掌握Rust开发。

  • 通过精简方式来整理核心语法、更方便后续知识点速查、回顾。

  •  参考The Rust Programming Language & Rust in Action

一.变量

  • 变量声明使用let, 默认为不可变(即只读),声明可变变量 mut (可读写)

 let x = 5;  //类型可以由编译器自动推断出来
 let y: i32 = 6;  //或者是在创建变量时,声明类型
 let z = 7i32;  //数字类型,可以在数字字面量中加入类型注解

二. 基本数据类型

数字类型:
  • 分为有符号和无符号整数,浮点数类型、特定平台的整数

  •  每一个有符号的变体可以储存包含从 -2n-1 到2n-1-1 在内的数字,这里 n 是变体使用的位数。如:i8 范围(-128-127)

  • 无符号的范围为0到 2n-1,如: u8 范围(0-255)(00000000 - 11111111)

类型 长度 描述
i8, i16, i32, i64, i128 8,16,32,64,64,128 (bit) 有符号整数
u8, u16, u32, u64, u128 8,16,32,64,64,128 (bit) 无符号整数
f32, f64 32,64(位) f32 是单精度浮点数,f64 是双精度浮点数
isize, usize 32或64 32 位架构上它们是 32 位的,64 位架构上它们是 64 位的
Rust中的整型字面值:
数字字面值 描述
Decimal (十进制) 1_100 (使用 _ 做为分隔符以方便读数)
Hex (十六进制) 0xff(0x开头)
Octal (八进制) 0o77 (0o开头)
Binary (二进制) 0b1111_0000(0b开头)
Byte (单字节字符)(仅限于u8) b'A'(b开头)
布尔类型 bool:
fn main() {
    let t = true;
    let f: bool = false; // with explicit type annotation
}
复合类型:
  •  元组(tuple)和数组(array)

  • Tuple: 将多个其他类型的值组合进一个复合类型,声明后长度固定,索引下标从0开始.

    let tup: (i32, f64, u8) = (500, 8.4, 2); //声明类型
    let score = ("Team A", 12); //自推断
    let five_hundred = tup.0; //取出元组里的500,下标0
  • array: 数组里数据类型必须一致,长度固定

let a = [1, 2, 3, 4, 5]; // 自推断
let b: [i32; 5] = [1, 2, 3, 4, 5]; // 在方括号中包含每个元素的类型,后跟分号,再后跟数组元素的数量。
let c = [3; 5]; //变量名为c的数组将包含 5 个元素,数值都为3,等价与let a = [3, 3, 3, 3, 3]

三. 流程控制

if & if let:
    let number = 3;
    if number < 5 {
        println!("condition was true");
    } else {
        println!("condition was false");
    }
    
  // match pattern and assign variable
    if let Some(i) = num {
        println!("number is: {}", i);
    }
   // if let 语法让我们以一种不那么冗长的方式结合 if 和 let,来处理只匹配一个模式的值而忽略其他模式的情况
loop:
    let mut count = 0;
    loop {
        count += 1;
        if count == 4 {
            println!("break");
            break;
        }
    }

Nested loops & labels (循环标签): 如果存在嵌套循环在一个循环上指定一个 循环标签(loop label) 标识为'名字

    'outer: loop {
        'inner: loop {
            break; // This breaks the inner loop
            break 'outer; //   // This breaks the outer loop
        }
    }
while & while let:
    while n < 101 {
        n += 1;
    }
    let mut optional = Some(0);
    while let Some(i) = optional {
        print!("{}", i);
    }
for 遍历集合:
    let a = [10, 20, 30, 40, 50];
    for element in a {
        println!("the value is: {element}");
    }
    
    //使用iter()
    let array = [(1, 2), (2, 3)];
    for (x, y) in array.iter() {
        // x, y accessible in loop body only
        println!("x={},y={}", x, y);
    }
match:
    let optional = Some(0);
    match optional {
        Some(i) => println!("{}", i),
        None => println!("No value."),
    }

四.所有权&引用&借用

所有权规则:
Rust 中的每一个值都有一个 所有者(owner)
值在任一时刻有且只有一个所有者
当所有者(变量)离开作用域,这个值将被丢弃
借用规则:(引用的行为)
同一作用域内,一个资源要么有一个可变引用,要么存在多个不可变引用
引用总是有效的
String引用:
    let s1 = String::from("hello world!");
    let s1_ref = s1; // immutable reference
    let mut s2 = String::from("hello");
    let s2_ref = &mut s2; // mutable reference
    s2_ref.push_str(" world!");
  •  函数里使用值,但不获取所有权, 使用&,获取变量引用 ,仅读权限

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}
  • 函数里参数可变引用, 使用&mut ,获取变量可变操作

fn main() {
    let mut s = String::from("hello");
    change(&mut s);
}
//  对参数声明&mut ,操作写字符
fn change(some_string: &mut String) {
    some_string.push_str(", world");
    println!("{}", some_string);
}
操作符对应的权限:
x   不可变的值(所有权)
&x  x不可变的引用 (只读)
&mut x  x的可变引用(读写)
字符串 slice:
  •  slice 允许你引用集合中一段连续的元素序列,而不用引用整个集合。slice 是一类引用,它没有所有权

fn main() {
    let s = String::from("hello world");

    let hello = &s[0..5];
    let world = &s[6..11];
}

五. struct

  • 普通结构体:struct+一个名字,在大括号中每一部分可以是不同类型,定义每一部分数据的名字和类型,称之为结构体字段

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}
  • 创建一个实例需要以结构体的名字开头,接着在大括号中使用 key: value 键-值对的形式提供字段

    let userinfo = User {
        email: String::from("[email protected]"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
元组结构体(tuple structs):
  •  元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
}
类单元结构体(unit-like structs):
  • 没有任何字段的结构体

struct AlwaysEqual;
fn main() {
    let subject = AlwaysEqual;
}
impl为结构体添加方法:
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}
  •  &self 实际上是 self: &Self 的缩写。在一个 impl 块中,Self 类型是 impl 块的类型的别名。方法的第一个参数必须有一个名为 self 的Self 类型的参数

impl里的关联函数:
impl Rectangle {
    fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
}
  • 所有在 impl 块中定义的函数被称为 关联函数(associated functions),因为它们与 impl 后面命名的类型相关。我们可以定义不以 self 为第一参数的关联函数(因此不是方法),因为它们并不作用于一个结构体的实例

  •  多个 impl 块:每个结构体都允许拥有多个 impl 块, 但一个方法只能属于一个impl块。

六.Enum

  • 结构体给予将字段和数据聚合在一起的方法,像 Rectangle 结构体有 width 和 height 两个字段。而枚举给予你将一个值成为一个集合之一的方法。

enum IpAddrKind {
    V4,
    V6,
}
enum IpAddrKind {
    V4,
    V6,
}

fn main() {
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;
    route(IpAddrKind::V4);
    route(IpAddrKind::V6);
}

fn route(ip_kind: IpAddrKind) {}
枚举可以包含不同的类型:
enum Message {
    Quit, // 没有关联任何数据
    Move { x: i32, y: i32 }, //类似结构体包含命名字段
    Write(String), //包含单独一个 String
    ChangeColor(i32, i32, i32), //包含三个 i32
}
  • • 结构体和枚举还有另一个相似点:就像可以使用 impl 来为结构体定义方法那样,也可以在枚举上定义方法。这是一个定义于我们 Message 枚举上的叫做 call 的方法:

fn main() {
    enum Message {
        Quit,
        Move { x: i32, y: i32 },
        Write(String),
        ChangeColor(i32, i32, i32),
    }

    impl Message {
        fn call(&self) {
            // 在这里定义方法体
        }
    }

    let m = Message::Write(String::from("hello"));
    m.call();
}
标准库中实用的枚举:Option
enum Option<T> {
        None,
        Some(T),
    }
enum Result<T, E> {
    OK(T),
    Err(E),
}

第一波先介绍到这里,后边把第二波的整理出来。通过3-4波精简笔记方式,也是我一个个验证过的,能帮助快速掌握rust基础。

PS: 也欢迎大家评论和交流~ 更多文章也可关注微信公号:良技漫谈

猜你喜欢

转载自blog.csdn.net/LiangGang365/article/details/143280451