关键词:
变量与可变性
在rust中声明的变量默认是不可变的。
fn main()
let x = 5;
println!("The value of x is: x");
x = 6;
println!("The value of x is: x");
保存并使用cargo run
运行程序,可以看到如下提示:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
3 | println!("The value of x is: x");
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
For more information about this error, try `rustc --explain E0384`.
error: could not compile `variables` due to previous error
错误信息指出错误的原因是 不能对不可变变量 x 二次赋值
(cannot assign twice to immutable variable
x
),因为你尝试对不可变变量 x
赋第二个值。
尽管变量默认是不可变的,你仍然可以在变量名前添加 mut
来使其可变.
fn main()
let mut x = 5;
println!("The value of x is: x");
x = 6;
println!("The value of x is: x");
保存并使用cargo run
运行这个程序,可以看到如下提示:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
Finished dev [unoptimized + debuginfo] target(s) in 0.30s
Running `target/debug/variables`
The value of x is: 5
The value of x is: 6
通过 mut
,允许把绑定到 x
的值从 5
改成 6
。是否让变量可变的最终决定权仍然在你,取决于在某个特定情况下,你是否认为变量可变会让代码更加清晰明了。
常量(const)
类似于不可变变量,常量(constants) 是绑定到一个名称的不允许改变的值,不过常量与变量还是有一些区别。
-
首先,不允许对常量使用
mut
。常量不光默认不能变,它总是不能变。 -
声明常量使用
const
关键字而不是let
,并且 必须 注明值的类型。 -
常量可以在任何作用域中声明,包括全局作用域,这在一个值需要被很多部分的代码用到时很有用。
-
最后一个区别是,常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出的值。
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
常量的名称是 THREE_HOURS_IN_SECONDS
,它的值被设置为 60(一分钟内的秒数)乘以 60(一小时内的分钟数)再乘以 3(我们在这个程序中要计算的小时数)的结果。Rust 对常量的命名约定是在单词之间使用全大写加下划线。编译器能够在编译时计算一组有限的操作,这使我们可以选择以更容易理解和验证的方式写出此值,而不是将此常量设置为值10,800。有关声明常量时可以使用哪些操作的详细信息,请参阅 Rust Reference 的常量求值部分。
隐藏
我们可以定义一个与之前变量同名的新变量。Rustacean 们称之为第一个变量被第二个 隐藏(Shadowing) 了,这意味着当您使用变量的名称时,编译器将看到第二个变量。实际上,第二个变量“遮蔽”了第一个变量,此时任何使用该变量名的行为中都会视为是在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。可以用相同变量名称来隐藏一个变量,以及重复使用 let
关键字来多次隐藏,如下所示:
fn main()
let x = 5;
let x = x + 1;
let x = x * 2;
println!("The value of x in the inner scope is: x");
println!("The value of x is: x");
这个程序首先将 x
绑定到值 5
上。接着通过 let x =
创建了一个新变量 x
,获取初始值并加 1
,这样 x
的值就变成 6
了。然后,在使用花括号创建的内部作用域内,第三个 let
语句也隐藏了 x
并创建了一个新的变量,将之前的值乘以 2
,x
得到的值是 12
。当该作用域结束时,内部 shadowing 的作用域也结束了,x
又返回到 6
。运行这个程序,它会有如下输出:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
Finished dev [unoptimized + debuginfo] target(s) in 0.31s
Running `target/debug/variables`
The value of x in the inner scope is: 12
The value of x is: 6
隐藏与mut的区别
隐藏与将变量标记为 mut
是有区别的。当不小心尝试对变量重新赋值时,如果没有使用 let
关键字,就会导致编译时错误。通过使用 let
,我们可以用这个值进行一些计算,不过计算完之后变量仍然是不可变的。
mut
与隐藏的另一个区别是,当再次使用 let
时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字。例如,假设程序请求用户输入空格字符来说明希望在文本之间显示多少个空格,接下来我们想将输入存储成数字(多少个空格):
fn main()
let spaces = " ";
let spaces = spaces.len();
第一个 spaces
变量是字符串类型,第二个 spaces
变量是数字类型。隐藏使我们不必使用不同的名字,如 spaces_str
和 spaces_num
;相反,我们可以复用 spaces
这个更简单的名字。然而,如果尝试使用 mut
,将会得到一个编译时错误,如下所示:
fn main()
let mut spaces = " ";
spaces = spaces.len();
这个错误说明,我们不能改变变量的类型:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
--> src/main.rs:3:14
|
2 | let mut spaces = " ";
| ----- expected due to this value
3 | spaces = spaces.len();
| ^^^^^^^^^^^^ expected `&str`, found `usize`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` due to previous error
简要说明:
- 隐藏就是可以通过
let
关键字使同一个变量名更改不同的值,包括数据类型。 mut
关键字,是在不改变数据类型的情况下,更改其他值。
rust学习--变量(代码片段)
0x0每种编程语言都有变量的概念,我们可以把变量理解为最简单的存储方式,它是编码过程中是必不可少的。Rust的变量很有特色。变量不可变的特性让人想起了Erlang。以及后面的模式匹配,我觉得作者应该受Erlang影响很大。下... 查看详情
rust语言圣经07-变量绑定与解构(代码片段)
...让我们开门见山来谈谈,为何Rust选择了手动设定变量可变性。为何要手动设置变量的可变性?在其它大多数语言中,变量一旦创建,要么是可变的,要么是不可变的(ClosureScript),前者为编程提供了灵活性,... 查看详情
rust学习笔记-变量和类型(代码片段)
变量通常一门的语言的变量是没有啥可以说道的,无法就是变量命名规则:以字母、下划线和数字组成,并且数字不能开头,没啥好说的。但rust的变量奇怪的地方是,变量不可变譬如这样一个简单到不能再简... 查看详情
rust学习笔记-变量和类型(代码片段)
变量通常一门的语言的变量是没有啥可以说道的,无法就是变量命名规则:以字母、下划线和数字组成,并且数字不能开头,没啥好说的。但rust的变量奇怪的地方是,变量不可变譬如这样一个简单到不能再简... 查看详情
rust编程语言入门之高级特性(代码片段)
...级Trait高级类型高级函数和闭包宏一、不安全Rust匹配命名变量隐藏着第二个语言,它没有强制内存安全保证:UnsafeRust(不安全的Rust)和普通的Rust一样,但提供了额外的“超能力”UnsafeRust存在的原因:静态分析是保守的。使用Un... 查看详情
rust编程语言三(代码片段)
Rust编程语言三fnmain()//所有权规则变量作用域//变量范围是变量的一个属性,其代表变量的可行域,默认从声明变量开始有效直到变量所在域结束。//这里未创建变量s此时s不可用lets="abc";//这里创建了变量s此时s可... 查看详情
rust语言教程-从熟悉的部分开始(代码片段)
...始。数据类型与Go一样,Rust的定义语句数据也是放在变量名后面的& 查看详情
rust语言特性之变量
...ff0c;所以有很多独特之处。今天我就来聊一聊RUST语言中的变量。所有的编程语言都有变量,RUST语言在设计上独特地方在于:Rust中的变量默认是不可变的。一个新声明的变量可以覆盖掉旧的同名变量。如果仅仅是学习语言... 查看详情
rust内存安全--借用(代码片段)
...;总结一句话是“共享不可变,可变不共享”譬如这段代码,是可以通过编译的fnmain()leti=1;letp1=&i;letp2=&i;println!("",i,p1,p2);虽然发送了共享,但没有修改其内容,是安全的 查看详情
rust内存安全--借用(代码片段)
...前的原则,i的确借用给了p1,在p1的生命周期内i变量是被冻结的,不能读写,但p1使用结束后,i变量又回到之前状态,继续可以使用,并没有冲突。如果是使用&mu 查看详情
rust内存安全--借用(代码片段)
...前的原则,i的确借用给了p1,在p1的生命周期内i变量是被冻结的,不能读写,但p1使用结束后,i变量又回到之前状态,继续可以使用,并没有冲突。如果是使用&mu 查看详情
如何对 Rust 数组的 2 个可变切片进行操作?
...能够构建一个#[nostd]分配器,该分配器可以将更大数组的变量切片返回给调用者,并保留数组的其余部分以供将来分配。这是失败的示例代码:fnsplit<\'a>(mutit 查看详情
rust全局变量
参考技术A在实际项目开发中,难免需要用到全局变量,比如全局配置信息,全局内存池等,此类数据结构可能在多处需要被使用,保存为全局变量可以很方便的进行修改与读取。在Rust中,如果只是读取静态变量是比较简单的,... 查看详情
“不能返回引用临时值的值”和 Rust 中的内部可变性
】“不能返回引用临时值的值”和Rust中的内部可变性【英文标题】:"cannotreturnvaluereferencingtemporaryvalue"andinteriormutabilityinRust【发布时间】:2021-05-1904:28:15【问题描述】:我在Rust中有以下代码:pubstructRegExpFilter...regexp_data:R... 查看详情
23.rust-集合(collections)(代码片段)
Rust语言标准库提供了通用的数据结构的实现。包括向量(Vector)、哈希表(HashMap)、哈希集合(HashSet)。向量(Vector)Rust在标准库中定义了结构体Vec用于表示一个向量。向量和数组很相似,只是数组长度是编译时就确定了,... 查看详情
scala基础知识(代码片段)
1.scala的变量分为可变变量和不可变变量 不可变变量:valhello="helloworld"可变变量的定义方法varstr2="我是kw!"不可变变量相当于java中的final关键字修饰的数据,可变变量相当于java中的变量,对于scala语言而言,更希望使用的val... 查看详情
swift函数式编程六(不可变性的价值)(代码片段)
代码地址变量Swift中的变量有两种,一种是不可变变量(用let申明),另一种是可变变量(用var申明)。很显然,不可变变量会限制变量的能力,通常可变变量的使用更加广泛。但是往往事实恰恰相... 查看详情
swift函数式编程六(不可变性的价值)(代码片段)
代码地址变量Swift中的变量有两种,一种是不可变变量(用let申明),另一种是可变变量(用var申明)。很显然,不可变变量会限制变量的能力,通常可变变量的使用更加广泛。但是往往事实恰恰相... 查看详情