2024-02-13
24T1
00

目录

变量声明
普通变量
重影(Shadowing)
数组
VEC
复合类型tuple
枚举类型enum
Option枚举
变量类型
大括号的返回值
循环 (需要补充)
For循环
While循环
Loop循环
所有权规则

COMP6991 Solving Modern Programming Problems with Rust

记录RUST相关基本语法。

变量声明

普通变量

RUST
//不可变变量 let s = 100; //可变变量(mutable) let mut s = 100; //类型变量 let mut s = String::new();

重影(Shadowing)

重影是指变量的名称可以被重新使用的机制(多次重复使用let):

RUST
fn main() {     let x = 5;     let x = x + 1;     let x = x * 2;     println!("The value of x is: {}", x); }

重影与可变变量的赋值不是一个概念,重影是指用同一个名字重新代表另一个变量实体。

重影变量的类型、可变属性和值都可以变化。

可变变量赋值仅能发生值变化。

在同一范围内多次声明同名变量,后声明的变量会隐藏(遮蔽)前面的同名变量。这意味着在同一作用域内,后声明的变量会覆盖前面的同名变量,而前面的同名变量则不再可见。

需要注意的是,在不同的作用域中,不同的x在事实上是同时存在的,而不是后者取代前者的关系。

RUST
let x = 42; { let x = 123; println!("The value is: {x:?}"); } println!("{x}");

输出的结果是:

The value is: 123 42

数组

数组创建时声明类型与长度。也可以不写,编译器会自动处理。

RUST
fn main() { let my_array: [i32; 5] = [ 1, 2, 3, 4, 5, ] }

VEC

使用vec!创建VEC,并且能够使用push添加变量。

RUST
let mut my_vec = vec![1, 2, 3]; my_vec.push(42);

复合类型tuple

可以直接将一个变量内部声明多个变量。

RUST
let my_tuple: (bool, i32, char) = (true, 42, 'z'); let my_tuple: (i32) = (7); let unit_tuple = ();

注意:空tuple一般不能作为bool变量的判断。

RUST
let unit_tuple = (); //非法,不可编译通过 if unit_tuple { } //合法 if unit_tuple == () { }

枚举类型enum

首先枚举不同种类的选项,之后可以自由使用。

RUST
enum CarBrand { Toyota, Nissan, Subaru, } fn main() { let brand: CarBrand = CarBrand::Toyota; //注意,以下写法是不合法的 let brand = CarBrand::Toyota; }

同时,这些类型一样可以声明成不同的变量类型,之后直接赋值(变量类型请见下文)。

RUST
enum CarBrand { Toyota(i32), Nissan(String), Subaru, } fn main() { let brand: CarBrand = CarBrand::Toyota(42); let brand: CarBrand = CarBrand::Nissan(String::form("HelloWorld")); }

Option枚举

Option是一个枚举类型,用于表示一个值可能存在也可能不存在的情况。这个类型被广泛用于处理可能为空的情况,类似于其他语言中的可选类型或者空安全类型。Option枚举有两个可能的值:

  • Some(T): 表示值存在,并且包含了类型为 T 的具体值。
  • None: 表示值不存在,没有具体的值。

这个模式允许程序员在可能返回空值的情况下更好地处理代码,以避免空指针异常或者其他类似的错误。

例如,一个简单的函数可能会返回一个Option类型,表明它可能返回一个值,也可能返回空值:

RUST
fn main() { let some_value: Option<i32> = Some(5); // 创建一个包含整数值的 Some let no_value: Option<i32> = None; // 创建一个空的 Option match some_value { Some(value) => println!("Value is: {}", value), // 如果存在值,则打印值 None => println!("No value!"), // 如果不存在值,则打印"无值" } match no_value { Some(value) => println!("Value is: {}", value), // 如果存在值,则打印值 None => println!("No value!"), // 如果不存在值,则打印"无值" } }

在这个简短的示例中,我们定义了两个 Option<i32> 类型的变量:some_valueno_value

some_value包含了一个具体的整数值5,而no_value则是一个空的Option。然后,我们使用match来检查这些变量,如果存在值,则打印该值,否则打印 "无值"。

变量类型

经典的变量有以下几种:

char, short, int, long, long long i8, i16, i32, i64, i128 u8, u16, u32, u64, u128 float, double f32, f64

由于RUST的运行环境的位数不同,例如在32位和64位的机器上,变量的位数可能会发生变化,因此规定变量的位数是很有必要的。

规定位数的方式:

RUST
let x: u8 = 42;

变量之间也可以进行强制类型转换,但是存在风险(dirty way)。

RUST
let x: u8 = 42; let y: i32 = x as i32;

推荐的方法是使用into来进行风险预警。

RUST
let x: i32 = 1231231123; let y: u8 = x.into();

如果可能会出现丢失数据的情况发生,它会报错并发出预警。

发出自定义预警的方法:

RUST
let x: i32 = 1231231123; let y: u8 = x.into().expect("Number was too big");

这样在触发报警的时候会抛出“Number was too big”。

大括号的返回值

大括号的返回值只取决于最后一行。

RUST
let judge = { let mut a = 4; a = a * a; a += 12; //最终给judge赋的值 a/4 };

循环 (需要补充)

For循环

标准形式:

RUST
fn main() { let my_array = [10, 20, 30, 40, 50];     for i in 0..5 {         println!("my_array[{}] = {}", i, my_array[i]);     } }

但RUST也支持数组元素直接访问。

RUST
let my_array = [ 1, 2, 3, 4, 5, ] for elem in my_array { println!("{elem}"); }

While循环

Loop循环

所有权规则

RUST
let my_string = String::form("HelloWorld"); let output_string = my_string; //能够正常输出 println!("{output_string}"); //会报错 println!("{my_string}");

String 类型是可变的、拥有所有权的类型,而在你的代码中,你把 my_string 绑定到了一个新的 String 实例上,然后尝试再次使用 my_string 来打印其值,这违反了所有权规则

在 Rust 中,所有权规则保证了内存安全和避免了数据竞争。当你把 my_string 赋值给 output_string 后,所有权被转移了,output_string 拥有了 my_string 的所有权,而 my_string 不再有效。因此,尝试打印 my_string 的值会导致编译错误,因为它已经无效。

要修复这个问题,你可以通过使用 clone() 方法来克隆 my_string,以保留原始值并创建一个新的 String 实例,而不是直接将所有权转移给另一个变量。例如:

RUST
let my_string = String::from("HelloWorld"); let output_string = my_string.clone(); println!("{output_string}"); println!("{my_string}");

因此,在RUST中,进行复制(Copy)操作时一定要考虑所有权的问题。

本文作者:Jeff Wu

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!