类型

基元类型

rust中内置的基元类型有以下几种:

  • bool
  • char
  • integer
  • isize
  • usize
  • f32
  • f46
  • [T;N] 固定大小的数组
  • [T] 动态大小的连续序列的视图
  • str 字符串切片
  • (T, U, ..) 有限序列

    不可变变量、可变变量和常量

    在Rust中,存在着 不可变变量 , 可变变量常量 的区别。

在 Rust 中定义的变量,默认是不可变的。声明如下:

  1. let space = " ";

在 Rust 中,变量一旦声明就不允许改变了。但是,在Rust中,还存在着一种叫做 覆盖 (Shadow)的行为。如下所示:

  1. let x = 5;
  2. let x = x + 1;
  3. let x = x * 2;

最后 的结果,i=12。Rust中的 覆盖可变变量 都可以让之前声明的变量的值发生改变。但还是有所不同的:

  • 可变变量 只能修改变量的值,不能修改其类型。而 覆盖 不仅可以修改变量的值,而且可以修改变量的类型。
  • 可变变量 在声明后的所有地方都可以修改其值。而 覆盖 的值的修改,只能再以 覆盖 的形式去修改。

常量 是在永远不能修改的值。用 const 声明。

  1. const PI = 3.1415926;

数据类型

Rust语言是一个 静态类型 的语言。所有在使用的过程中,Rust 需要知道当前变量的类型。在一般情况下,Rust 可以自动推断出变量的类型。当Rust无法推断时,我们就要指出变量类型。比如:

  1. let n: u32 = 16;

在 Rust 中,有 标量复合 变量两类类型 。

标量

Struct

在Rust中,有一种叫 Struct 的数据结构,它类似于 其他语言中的 ,有自己的自定义结构和方法。但又比具体语言中的类要灵活许多。

基本结构

下面是基本的结构:

  1. struct Rect{
  2. width: u32,
  3. height: u32
  4. }
  5. struct Color(i32, i32, i32);
  6. struct Point(i32, i32, i32);
  7. let black = Color(0,0,0);
  8. let origin = Point(0,0,0);

实例方法

Ruststruct 中实现方法要用 impl 关键字。

  1. struct Rect {
  2. width: u32,
  3. height: u32
  4. }
  5. impl Rect {
  6. fn area(&self) -> u32 {
  7. self.width * self.height
  8. }
  9. fn can_hold(&self, other: &Rect) -> bool {
  10. self.width > other.width && self.height > other.height
  11. }
  12. }

Rust 中,实现的实例语法的第一个参数总是 &self ,代表着实例本身。而其他实体变量则以 类的引用 类型传入。

静态方法

Ruststruct 中实现静态方法使用没有 &self 的函数完成。

  1. impl Rect {
  2. fn square(&size: u32) -> Rect {
  3. Rect {
  4. width: size,
  5. height: size
  6. }
  7. }
  8. }

注意:Rust 中,并不要求把 struct 所有的实现都写在同一个 impl 中。可以把实现分开放在不同的 impl 语句中。

枚举

Rust 中同样有枚举类型,而且枚举类型比其他语言中的要更加丰富。如:

  1. enum IPAddr {
  2. V4(u8, u8, u8, u8),
  3. V6(String)
  4. }
  5. enum Message {
  6. Quit,
  7. ChangeColor(i32, i32 ,i32)
  8. }
  9. impl Message {
  10. fn call(&self) {
  11. // method body would defined here
  12. }
  13. }

自定义判别值

Rust中,枚举类型还支持无字段的自定义判别值。如下:

  1. enum Foo {
  2. Bar, // 0
  3. Baz = 123, // 123
  4. Quux, // 123
  5. }

在上面的例子中,枚举FooBar字段没有指定值,所以判别值为0。而字段Baz显式指定了123,所以判别值为123,紧挨着BazQuux字段是Baz的判别值+1的值,即124
需要注意的是,Rust中的枚举类型的判别值的类型默认为isize(当然,我们可以使用as关键字把个别值转换为其他类型)。
当我们需要指定枚举判别值的类型的时候,我们可以使用repr这个tract。如下:

  1. #[repr(u8)]
  2. enum Foo {
  3. Bar,
  4. Baz = 123,
  5. Quux,
  6. }

在指定枚举判别值的时候,无论是我们手动指定的还是Rust通过推导出来的都不能和已有的判别值有冲突。比如以下的两个枚举类型都是错误的:

  1. // 手动指定的判别值存在冲突的错误
  2. enum SharedDiscriminantError {
  3. SharedA = 1,
  4. SharedB = 1,
  5. }
  6. // Rust推导出来的判别值存在冲突的错误
  7. enum SharedDiscriminantError2 {
  8. Zero, // 0
  9. One, // 1
  10. OneToo, // 1 (collision with previous!)
  11. }

在枚举的判别值超出范围后,同样会发生错误。如下:

  1. #[repr(u8)]
  2. enum OverflowingDiscriminantError {
  3. Max = 255,
  4. MaxPlusOne // would be 256, but that overflows the enum.
  5. }

Option枚举

Rust 中不存在 null 类型,但是存在一个叫 Option 的枚举。如下:

  1. enum Option<T> {
  2. Some(T),
  3. None
  4. }

match操作符

match操作符:

  1. fn plus_one(x: Option<i32>) -> Option<i32> {
  2. match x {
  3. Some(x) => Some(x+1),
  4. Node => None,
  5. }
  6. }

_ 占位符

Rustmatch中有一个特殊的占位符。它能占用所有的情况。它就是 _ 。如下:

  1. let some_u8_value = 0u8;
  2. match some_u8_value {
  3. 1 => println!("one"),
  4. 3 => println!("three"),
  5. 5 => println!("five"),
  6. 7 => println!("seven"),
  7. _ => (),
  8. }