Rust学习:3_变量绑定与解构
前言
为了学习Rust,阅读了github上的Rust By Practice电子书,本文章只是用来记录自己的学习过程,感兴趣的可以阅读原书,希望大家都能掌握Rust!
绑定和可变性
1.🌟 变量只有在初始化后才能被使用
// 修复下面代码的错误并尽可能少的修改
fn main() {
let x: i32; // 未初始化,但被使用
let y: i32; // 未初始化,也未被使用
println!("x is equal to {}", x);
}
变量声明了但是未被使用将报错:
warning: unused variable: `y`
--> .\main.rs:4:9
|
4 | let y: i32 = 2; // 未初始化,也未被使用
| ^ help: if this is intentional, prefix it with an underscore: `_y`
|
= note: `#[warn(unused_variables)]` on by default
warning: 1 warning emitted
✅修改:
// 修复下面代码的错误并尽可能少的修改
fn main() {
let x: i32 = 1; // 未初始化,但被使用
// let y: i32; // 未初始化,也未被使用
println!("x is equal to {}", x);
}
运行:
x is equal to 1
2.🌟🌟 可以使用 mut
将变量标记为可变
// 完形填空,让代码编译
fn main() {
let __ = 1;
__ += 2;
println!("x = {}", x);
}
let x = 1
声明的变量x
的值无法被修改,因此在运行x += 2
时会报错。需要在变量x
前添加mut
,将变量标记为可变
✅修改:
// 完形填空,让代码编译
fn main() {
let mut x = 1;
x += 2;
println!("x = {}", x);
}
运行
x = 3
变量作用域
3.🌟 作用域是一个变量在程序中能够保持合法的范围
// 修复下面代码的错误并使用尽可能少的改变
fn main() {
let x: i32 = 10;
{
let y: i32 = 5;
println!("x 的值是 {}, y 的值是 {}", x, y);
}
println!("x 的值是 {}, y 的值是 {}", x, y);
}
✅修改1:
将let y: i32 = 5;
写在{}
的作用域外,{}
内的语句和{}
外的语句访问的都是同一个y
// 修复下面代码的错误并使用尽可能少的改变
fn main() {
let x: i32 = 10;
let y: i32 = 5;
{
println!("x 的值是 {}, y 的值是 {}", x, y);
}
println!("x 的值是 {}, y 的值是 {}", x, y);
}
运行:
x 的值是 10, y 的值是 5
x 的值是 10, y 的值是 5
✅修改2:
在{}
外重新声明一个变量y
,{}
内的语句将访问里面的y(5)
,{}
外的语句将访问外面的y(7)
// 修复下面代码的错误并使用尽可能少的改变
fn main() {
let x: i32 = 10;
let y: i32 = 7;
{
let y: i32 = 5;
println!("x 的值是 {}, y 的值是 {}", x, y);
}
println!("x 的值是 {}, y 的值是 {}", x, y);
}
运行:
x 的值是 10, y 的值是 5
x 的值是 10, y 的值是 7
4.🌟🌟
// 修复错误
fn main() {
println!("{}, world", x);
}
fn define_x() {
let x = "hello";
}
✅修改:
在main()
中声明一个变量x
// 修复错误
fn main() {
let x = "hello";
println!("{}, world", x);
}
/*
fn define_x() {
let x = "hello";
}
*/
运行:
hello, world
变量遮蔽( Shadowing )
5.🌟🌟 若后面的变量声明的名称和之前的变量相同,则我们说:第一个变量被第二个同名变量遮蔽了( shadowing )
// 只允许修改 `assert_eq!` 来让 `println!` 工作(在终端输出 `42`)
fn main() {
let x: i32 = 5;
{
let x = 12;
assert_eq!(x, 5);
}
assert_eq!(x, 12);
let x = 42;
println!("{}", x); // 输出 "42".
}
运行:
assert_eq!(x,5)
左右侧不等时将会panic!,程序要通过需要使左右侧的值相等
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `12`,
right: `5`', ex5.rs:6:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
✅修改:
// 只允许修改 `assert_eq!` 来让 `println!` 工作(在终端输出 `42`)
fn main() {
let x: i32 = 5;
{
let x = 12;
assert_eq!(x, 12);
}
assert_eq!(x, 5);
let x = 42;
println!("{}", x); // 输出 "42".
}
运行:
42
6.🌟🌟 删除一行代码以通过编译
fn main() {
let mut x: i32 = 1;
x = 7;
// 遮蔽且再次绑定
let x = x;
x += 3;
let y = 4;
// 遮蔽
let y = "I can also be bound to text!";
}
运行rustc
编译
error[E0384]: cannot assign twice to immutable variable `x`
--> ex6.rs:7:5
|
6 | let x = x;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
7 | x += 3;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error; 5 warnings emitted
✅修改:
// 删除一行代码以通过编译
fn main() {
let mut x: i32 = 1;
x = 7;
// 遮蔽且再次绑定
// let x = x;
x += 3;
let y = 4;
// 遮蔽
let y = "I can also be bound to text!";
}
运行rustc
编译,虽然有warning
但是编译通过
warning: variable `x` is assigned to, but never used
--> ex6.rs:3:13
|
3 | let mut x: i32 = 1;
| ^
|
= note: `#[warn(unused_variables)]` on by default
= note: consider using `_x` instead
warning: value assigned to `x` is never read
--> ex6.rs:7:5
|
7 | x += 3;
| ^
|
= note: `#[warn(unused_assignments)]` on by default
= help: maybe it is overwritten before being read?
warning: unused variable: `y`
--> ex6.rs:10:9
|
10 | let y = 4;
| ^ help: if this is intentional, prefix it with an underscore: `_y`
warning: unused variable: `y`
--> ex6.rs:12:9
|
12 | let y = "I can also be bound to text!";
| ^ help: if this is intentional, prefix it with an underscore: `_y`
warning: 4 warnings emitted
未使用的变量
7.使用以下方法来修复编译器输出的 warning :
- 🌟 一种方法
- 🌟🌟 两种方法
注意: 你可以使用两种方法解决,但是它们没有一种是移除 let x = 1
所在的代码行
fn main() {
let x = 1;
}
// compiler warning: unused variable: `x`
✅修改1:
fn main() {
let x = 1;
println!("x is equal to {}",x);
}
// compiler warning: unused variable: `x`
运行:
x is equal to 1
✅修改2:
warning: unused variable: `x`
--> ex7.rs:3:9
|
3 | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
= note: `#[warn(unused_variables)]` on by default
warning: 1 warning emitted
在变量名前添加_
表示该变量可能不会被使用
fn main() {
let _x = 1;
}
// compiler warning: unused variable: `x`
变量解构
8.🌟🌟 我们可以将 let
跟一个模式一起使用来解构一个元组,最终将它解构为多个独立的变量
提示: 可以使用变量遮蔽或可变性
// 修复下面代码的错误并尽可能少的修改
fn main() {
let (x, y) = (1, 2);
x += 2;
assert_eq!(x, 3);
assert_eq!(y, 2);
}
✅修改:
// 修复下面代码的错误并尽可能少的修改
fn main() {
let (mut x, y) = (1, 2);
x += 2;
assert_eq!(x, 3);
assert_eq!(y, 2);
}
解构式赋值
9.🌟🌟
Note: 解构式赋值只能在 Rust 1.59 或者更高版本中使用
fn main() {
let (x, y);
(x,..) = (3, 4);
[.., y] = [1, 2];
// 填空,让代码工作
assert_eq!([x,y], __);
}
✅修改:
fn main() {
let (x, y);
(x, ..) = (3, 4);
[.., y] = [1, 2];
// 填空,让代码工作
assert_eq!([x,y], [3,2]);
}