• Rust 从入门到精通04-变量


    🚀 优质资源分享 🚀

    学习路线指引(点击解锁)知识定位人群定位
    🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
    💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统
    目录

    回到顶部### 1、变量声明语法

    Rust 变量必须先声明,后使用。

    对于局部变量,常见是声明语法为:

    let variable : i32 = 100;

    由于 Rust 是有自动推导类型功能的,所以后面的 :i32 是可以省略的。

    1.1 语法解析更容易

    局部变量声明一定是以 let 开头,类型一定是跟在冒号 : 的后面。语法歧义更少,语法分析器更容易编写。

    1.2 方便引入类型推导功能

    Rust 声明变量的特点:要声明的变量前置,类型描述后置。
    这是因为在变量声明语句中,最重要的是变量本身,而类型其实是个附属的额外描述,并非必不可少的部分。如果我们可以通过上下文环境由编译器自动分析出这个变量的类型,那么这个类型描述完全可以省略不写。

    PS:Rust 支持类型推导,在编译器能够推导类型的情况下,变量类型一般可以省略,但常量(const)和静态变量(static)必须声明类型。

    Rust 从一开始就考虑了类型自动推导功能,因此类型后置的语法更加合适。

    1.3 模式解构

    pattern destructure
    比如将变量由只读变为可读写(mut声明)

    回到顶部### 2、变量命名规则

    Rust 里的合法标识符(包括变量名、函数名、trait名等)必须由:
    ①、数字
    ②、字母
    ③、下划线
    注意:不能以数字开头!!!

    另外:要注意下划线 _ 的特殊用法。

    回到顶部### 3、变量遮蔽

    Rust 允许在同一个代码块中声明同样名字的变量,后面声明的变量会将前面声明的变量“遮蔽”起来。

    //变量遮蔽
    fn variable\_masking(){
        let x = "123";
        println!("{}",x);
    
        let x = 1;
        println!("{}",x);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注意:这样做并不会产生内存安全问题,因为我们对这块内存拥有完整的所有权,且此时并没有任何其它引用指向这个变量,对这个变量的修改是完全合法的。

    回到顶部### 4、变量类型推导

    Rust的类型推导有两种:
    ①、从变量声明的当前语句中获取信息进行推导
    ②、通过上下文信息进行推导

    //类型推导
    fn type\_derivation(){
        //1.1 没有明确标出变量类型,但是通过字面量的后缀,编译器知道x的类型是 u8
        let x = 5u8;
        //1.2 通过字面量值 1,编译器知道y 的类型是 i32
        let y = 1;
    
        //1.3 创建一个动态数组,但是没有声明数组里面是什么类型
        let mut vec = Vec::new();
        //编译器通过添加的元素 1 ,推导出 vec 的实际类型是 Vec
        vec.push(1);
    
        println!("{}",x);
        println!("{}",y);
        println!("{:?}",vec);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    回到顶部### 5、类型别名

    通过 type 关键字给同一个类型起个别名。

    //类型别名
    fn type\_alias(){
        //将 i32 这种数据类型起别名为 int
        type int = i32;
        let x : int = 1;
        println!("{}",x);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    类型别名还可以用于泛型场景:

    type Double = (T,Vec);

    那么,以后使用 Double 的时候,就等同于(i32,Vec)

    回到顶部### 6、不可变 mut

    Rust 声明的变量默认是不可变的。

    默认不可变,这是一个很重要的特性,它符合最小权限原则,有助于我们写出正确且健壮的代码。

    // 变量不可变
    fn variable\_mut(){
        let i = 123;
        i = 2;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    编译报错:

    如果要使得变量可变,必须要用关键字 mut 声明:

    fn variable\_mut(){
        let mut i = 123;
        i = 2;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    当你使用 mut 却没有修改变量,Rust 编译期会友好地报警,提示你移除不必要的 mut。

    fn main() {
        variable\_mut();
    }
    // 变量不可变
    fn variable\_mut(){
        let mut i = 123;
        println!("{}",i);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    编译器警告:

    回到顶部### 7、静态变量

    Rust 中通过 static 关键字声明静态变量,如下:

    static GLOBAL : i32 = 0;

    static 声明的变量的生命周期是整个程序,从启动到退出,static 变量的生命周期永远是 ‘static’,它占用的内存空间也不会在执行过程中被回收。

    这也是 Rust 中唯一声明全局变量的方法。

    由于 Rust 非常注重内存安全,因此全局变量的使用有很多限制:
    ①、全局变量必须在声明的时候马上初始化(对应局部变量可以先声明不初始化,只需要保证使用的时候初始化就行了,我们可以这样理解,全局变量是写在函数外面,而局部变量是写在函数内部,所以需要保证全局变量声明的时候就要初始化);
    ②、全局变量的初始化必须是编译期可确定的常量,不能包括执行期才能确定的表达式、语句和函数调用;
    ③、带有 mut 修饰的全局变量,在使用的时候必须使用 unsafe 关键字。

    回到顶部### 8、常量

    Rust 中通过 const 关键字声明常量。如下:

    const GLOBAL : i32 = 0;

    ①、使用 const 声明的是常量,而不是变量。因此不允许使用 mut 关键字修饰这个变量绑定。
    ②、常量的初始化表达式也一定要是一个编译期确定的常量,不能是运行期的值。

    注意:const 和 static 最大的区别在于编译器并不一定会给 const 常量分配内存空间,在编译过程中,它很可能会被内联优化。

    回到顶部### 9、变量声明常见错误

    9.1 变量必须初始化才能使用

    类型没有默认构造函数,变量值没有“默认值”

    fn main() {
        let x : i32;
        println!("{}",x);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    9.2 不能通过 mut 关键字修饰 const 声明的变量

    这个很容易理解,常量是不可变的,mut 表示可变,放一起语义冲突了。

    //mut和 const 不能一起使用
    fn const\_mut\_error(){
        const mut i : i32 = 1;
        println!("{}",i);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

  • 相关阅读:
    标记肽MGP-7-氨基-4-甲基香豆素、1926163-53-2、Met-Gly-Pro-AMC
    CSRF跨站请求伪造:django中如何攻击与防御
    什么是设计模式?
    LC655+offer070+offer069+offer072+662
    es6新语法特性+vue2的学习笔记
    【计算机组成原理】习题(一)—— 指令系统
    力扣(LeetCode)2530. 执行 K 次操作后的最大分数(C++)
    golang 值传递实例
    MySQL 高级(进阶) SQL 语句
    刷爆力扣之较大分组的位置
  • 原文地址:https://blog.csdn.net/m0_56069948/article/details/126157338