1、变量与可变性

需要知道何时适合不可变性,何时适合可变性

变量默认不可变

  • 值let绑定到名称上后就不能改变这个值
  • 对于不会变的值,我们不需要追踪它在哪里可能被修改,使得代码易于推导
  • 要和常量constants区分开

    • 不允许对常量使用mut,常量总是不能变
    • 常量使用const关键字而不是let,必须要注明类型
    • 常量可以在任何作用域中声明
    • 常量只能是常量表达式,不能是函数调用结果,不能是运行时计算出的值
    • 常量在整个程序生命周期中都有效
    • 常量可以方便维护

      mut声明可变变量

  • 可变变量的代码更容易写一点

  • 使用大型数据结构时。适当使用可变变量比复制+返回新实例更快;较小数据结构可以使用函数式风格,总是创建新的实例,代码更容易理解(可以为可读性而牺牲一定的性能)

    变量和常量区别

  • 不允许对常量使用mut,常量总是不能变

  • 常量使用const关键字而不是let,必须要注明类型
  • 常量可以在任何作用域中声明
  • 常量只能是常量表达式,不能是函数调用结果,不能是运行时计算出的值
  • 常量在整个程序生命周期中都有效

    • 常量可以方便维护

      隐藏shadowing

      可以定义一个与之前变量同名的新变量,新变量会隐藏之前的变量,后续使用这个变量时是看到第二个值
      mut和隐藏有区别
  • let隐藏可以改变类型,复用名字

    2、数据类型

    Rust中每个值都属于一个数据类型
    Rust是静态类型:编译时确定所有类型
    Rust可以进行类型推断,多种类型都有可能时必须有类型注解

  • 如使用parse将String转成数字时

    标量类型

    整型

  • 数字类型默认i32

  • 无符号u开头,有符号i开头
  • isize和usize依赖于计算机架构,64位架构上是64位的
  • 除了byte之外的所有数字字面值可以使用类型后缀,如57u8
  • 可以使用分隔符来方便读数,如1_000
  • 对整型溢出integer overflow,debug模式下会让程序panic;release下会进行二进制补码包装

浮点型
数值运算

      • / %

布尔类型

  • true和false

字符类型

  • Rust的char大小为4字节,代表unicode标量,能比ASCII表示更多内容

    复合类型

    将多个值合成类型
    两个Rust原生复合类型:tuple和array

    元组类型tuple

    1. let tup: (i32, f64, u8) = (500, 6.4, 1);
    2. let (x, y, z) = tup; //解构
    3. let one = x.2; //索引访问

    数组类型array

    如果想在栈上分配空间,或者确保元素数量固定时,数组好用
    数组不如vector灵活,vector允许增长或缩小长度
    不知道用数组还是vector,用vector

    1. let a = [1, 2, 3, 4];
    2. let a:[i32; 5] = [1, 2, 3, 4, 5];
    3. let a = [3; 5]; //[3, 3, 3, 3, 3]

    数组元素越界访问时

  • 程序会出现运行时错误,不会成功退出

  • 具体来说如果索引超出数组长度,Rust会panic
  • 很多底层语言不做这种检查,Rust能避开这类越界访问的错误和隐患

3、函数

fn关键字
Rust代码中函数和变量名的风格:小写字母+下划线
函数签名中,必须声明每个参数类型

语句和表达式

Rust是基于表达式的语言——不同于其他语言的重要点
语句statement

  • 执行操作但不返回值
  • let y = 6;

表达式expression

  • 计算并产生一个值
  • 表达式的结尾没有分号
  • x+1

4、注释

单行和多行注释,直接每行前面加”//“

5、控制流

基本情况

  • if条件不用加小括号
  • 条件必须是bool值,如果不是,会有错误

    let语句中使用if

  • 将if表达式的返回值赋给一个变量

  • 数字本身就是表达式
  • if每个分支的返回值必须是相同类型,否则错误

    • 因为Rust需要在编译时就知道number的类型,这样就可以静态验证每个地方对number进行使用时类型是有效的
      1. let number = if condition {
      2. 5
      3. }else{
      4. 6
      5. };

      循环

      loop

  • 不断重复执行代码

  • break退出循环,顺便可以返回表达式
  • 从循环返回表达式

    1. let result = loop {
    2. count += 1;
    3. if count==10 { break count*2; }
    4. };

    while

    1. while number!=0 {
    2. number = number-1;
    3. }

    for

  • 循环遍历集合元素时,使用while可能会出错,因为要手动维护集合容量 ```rust for element in a.iter() {}

for num in (1..4).rev() //反转range { println!(“{}”, num);} ```