[Rust] 变量的属性: 不可变(immutable), 可变(mutable), 重定义(shadowing), 常量(const), 静态(static)

变量的可变性

在 Rust 中, 变量可以具有下面的属性。

  • immutable: 不可变变量
  • mutable: 可变变量
  • shadowing: 重定义(遮蔽)一个变量
  • const: 常量
  • static: 静态变量

不可变变量(immutable) vs 可变变量(mut)

Rust 的安全哲学要求变量默认是不可变的。

fn main() {
// 定义一个不可变的变量
let x = 5;
// 错误: cannot assign twice to immutable variable `x`
// x = 6; // 定义一个可变的变量
let mut y = 5;
// 正确。可以改变!
y = y + 1; println!("{}", x + y);
}

重定义(shadowing) vs 可变变量(mut)

重定义(遮蔽)特性是一个 Rust 特有的语言特性。

相对于可变变量,重定义(遮蔽)一个变量,可以改变原有变量的数据类型和可变性。

fn main() {
// 定义一个不可变的变量
let x = 5; // 重定义变量 x。注意:变量类型和可变性都可以变。
// 变量 x 从整数数据类(i32)型变成了字符串数据类型(String)。
// 变量 x ,因为声明了 mut ,可变性也变成可变的。
let mut x: String = (x + 1).to_string();
// 正确。可以改变!
x = x + ":1"; println!("{}", x);
}

重定义特性的其它特点:

  • 重定义特性可以作用于不可变变量
  • 重定义特性可以作用于可变变量
  • 重定义特性不可以作用于 static 变量
  • 重定义特性不可以作用于 const 常量

常量(const)

常量的一个非常重要的特点是: 它的值会在编译时被 copy 到使用的地方。

注意:这种 copy 也会发生在外部包被编译的场合。因此,一定要确保你的常量不会在后续的开发中发生变化。

静态(static)

一个静态变量在应用中拥有唯一的内存地址。

大多数场合,静态变量会被定义为可变的。

在 Rust 的安全哲学中静态变量不是线程安全的,所以可变的静态变量在被读和写的场合,都需要标识 unsafe。

// 定义一个可变的静态变量
static mut LEVEL: i32 = 5;
// 定义一个不可变的静态变量
static CORRECT: i32 = 1; fn main() {
// 错误: note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
LEVEL = LEVEL + 1;
// 错误: note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
println!("{}", LEVEL);
// 正确: 不可变的静态变量是线程安全的。
println!("{}", CORRECT); // 读写静态变量都需要在unsafe中
unsafe {
// LEVEL = LEVEL + 1;
println!("{}", LEVEL);
}
}

静态(static) vs 常量(const)

那么,什么时候使用静态变量?什么时候使用常量呢?

  • 数据占有内存比较大的场合,使用静态变量;
  • 程序需要变量的地址属性的情况下,使用静态变量;
  • 变量需要是可变的情况下,使用静态变量;
  • 其它场合,推荐使用常量;

参照

[Rust] 变量的属性: 不可变(immutable), 可变(mutable), 重定义(shadowing), 常量(const), 静态(static)的更多相关文章

  1. Java中如何创建不可变(immutable)类

    什么是不可变类 1. 不可变类是指类的实例一经创建完成,这个实例的内容就不会改变. 2. Java中的String和八个基本类型的包装类(Integer, Short, Byte, Long, Dou ...

  2. python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变

    函数参数传递本质上和变量整体复制一样,只是两个变量分别为形参a和实参b.那么,a=b后,a变了,b值是否跟着变呢?这取决于对象内容可变不可变 首先解释一下,什么是python对象的内容可变不可变? p ...

  3. 可变对象(immutable)和不可变对象(mutable)

    可变对象(immutable)和不可变对象(mutable) 这个是之前一直忽略的一个知识点,比方说说起String为什么是一个不可变对象,只知道因为它是被final修饰的所以不可变,而没有抓住不可变 ...

  4. python学习之可变不可变

    在python的数据类型中,整数.字符串.元组是不可变的:而列表.字典是可变的.所以不用C的思维来修改一个整数,它相当于重新定义了一个整数(原来的被覆盖掉了),名字和原来一样,但与前面的同名变量没有一 ...

  5. 【rust】Rust变量绑定(3)

    Rust 是一个静态类型语言,这意味着我们需要先确定我们需要的类型. 什么是变量绑定? 将一些值绑定到一个名字上,这样可以在之后使用他们. 如何声明一个绑定? 使用 let 关键字: fn main( ...

  6. Python(可变/不可变类型,list,tuple,dict,set)

    补充:(可用操作技巧) >>> x=900 >>> y=900 >>> x==y True >>> type(x) is typ ...

  7. [Python] 可变/不可变类型 & 参数传递

    与c/c++不同,Python/Java中的变量都是引用类型,没有值类型 Python赋值语句由三部分构成,例如:   int   a  = 1 类型 标识 值 标识(identity):用于唯一标识 ...

  8. Python--基本数据类型(可变/不可变类型)

    目录 Python--基本数据类型 1.整型 int 2.浮点型 float 3.字符串 str 字符串格式 字符串嵌套 4.列表 list 列表元素的下标位置 索引和切片:字符串,列表常用 5.字典 ...

  9. runtime第二部分成员变量和属性

    接上一篇 http://www.cnblogs.com/ddavidXu/p/5912306.html 转载来源http://www.jianshu.com/p/6b905584f536 http:/ ...

  10. Java可变参数/可变长参数

    Java可变参数/可变长参数 传递的参数不确定长度,是变长的参数,例如小例子: package demo; public class Demo { public static int sum(int ...

随机推荐

  1. 测试环境Nginx反向代理负载均衡模板说明

    公司里面为了验证 https 以及域名特点进行了相关的测试工作.  为了简单起见 将 安装文件执行了导出. 这样的话就比较简单了. 注意说明一点的是 我这边导出的工具都是 放到根目录下面 目录最简单. ...

  2. Linux 通过yum 方式离线下载依赖rpm包的操作步骤

    离线下载依赖rpm包的方法 1.简单获取依赖关系 yum deplist rpm-build 注意 deplist 为依赖项目 我在arm 上面简单跑一下结果为 package: rpm-build- ...

  3. SQL注入payload学习整理

    SQLserver 用的payload 0101%'and 1=(select @@version) and '%'=' GS的一个客户端参数 <add PropertyName="F ...

  4. CoreDNS的配置文件修改

    CoreDNS的配置文件修改 今天浪费了4个小时来调整coredns 这里简单记录一下 注意修改点: 1 kubernetes cluster.local. 需要增加集群内的配置 2 forward ...

  5. postman数据驱动(.csv文件)

    做api测试的时候同一个接口我们会用大量的数据(正常流/异常流)去验证,要是一种场 景写一个接口的话相对于比较麻烦,这个时候就可以使用数据驱动来实现 1.本地创建一个txt文件,第一行写上字段名,多个 ...

  6. 2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币, 第i堆金币的总重量和总价值分别是m[i]、v[i], 阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的

    2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞.藏宝洞里面有N堆金币, 第i堆金币的总重量和总价值分别是m[i].v[i], 阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的 ...

  7. 结构体定义及结构体粒度(alignment)

    结构体定义及结构体粒度(alignment) #pragma pack(1) typedef struct _STUDENT_INFORMATION_ { int Age; char v1; int ...

  8. Mixed spaces and tabs

    ykit打包过程中报错信息如下: 报错原因: Mixed spaces and tabs(混合空格和制表符). 大多数代码约定要求使用空格或 tab 进行缩进,因此,一行代码若同时混有 tab缩进和空 ...

  9. 【druid切换hikari连接池】通过源码分析遇到的问题

    一.前言说明 如果不会配置druid连接池的话,可以参考我这篇博文:springboot整合druid: springboot整合所有的starter方法基本都差不多,添加依赖,开启注解,编写配置,增 ...

  10. 【主流技术】浅析 ElasticSearch7.x 的基本结构及应用(一)

    目录 前言 一.概述 1.1基本认识 1.2核心概念 对比关系型数据库 1.3倒排索引 例一: 例二: 1.4了解ELK 二.安装(基于 CentOS) 2.1安装声明 2.2 使用 Docker 安 ...