Rust 入门教程:变量到数据类型,轻松掌握!

Rust入门教程:变量到数据类型,轻松掌握!想学一门既强大又安全的编程语言?Rust绝对值得一试!这篇教程专为初学者打造,带你轻松掌握Rust的核心基础——从变量的声明与可变性,到数据类型和复合类型的应用。代码示例简单直观,零基础也能快速上手!快来一起探索Rust的魅力,开启你的系统编

Rust 入门教程:变量到数据类型,轻松掌握!

想学一门既强大又安全的编程语言?Rust 绝对值得一试!这篇教程专为初学者打造,带你轻松掌握 Rust 的核心基础——从变量的声明与可变性,到数据类型和复合类型的应用。代码示例简单直观,零基础也能快速上手!快来一起探索 Rust 的魅力,开启你的系统编程新旅程!

这篇 Rust 入门教程让你快速掌握编程基础!通过通俗的讲解和实用代码示例,带你学会变量与可变性、标量类型(整数、浮点数等)以及元组和数组的使用。无需复杂背景,轻松搞定 Rust 核心技能,适合所有编程新手!

变量与可变性

  • 声明变量使用let关键字
  • 默认情况下,变量是不可变的(Immutable)
    • (例子 variables)
  • 声明变量时,在变量前面加上mut,就可以使变量可变。
~/rust
➜ cargo new variables
     Created binary (application) `variables` package

~/rust
➜ cd var*

variables on  master [?] via 🦀 1.67.1
➜ code .

variables on  master [?] via 🦀 1.67.1
➜

代码

fn main() {
    println!("Hello, world!");

    let mut x = 5;
    println!("The value of x is {}", x);

    x = 6;
    println!("The value of x is {}", x);
}

变量与常量

  • 常量(constant),常量在绑定值以后也是不可变的,但是它与不可变的变量有很多区别:
    • 不可以使用mut,常量永远都是不可变的
    • 声明常量使用const关键字,它的类型必须被标注
    • 常量可以在任何作用域内进行声明,包括全局作用域
    • 常量只可以绑定到常量表达式,无法绑定到函数的调用结果或只能在运行时才能计算出的值
  • 在程序运行期间,常量在其声明的作用域内一直有效
  • 命名规范:Rust里常量使用全大写字母,每个单词之间用下划线分开,例如:MAX_POINTS
  • 例子:const MAX_POINTS: u32 = 100_000;

Shadowing(隐藏)

  • 可以使用相同的名字声明新的变量,新的变量就会shadow(隐藏)之前声明的同名变量
    • 在后续的代码中这个变量名代表的就是新的变量
  • Shadow 和把变量标记为mut是不一样的:
    • 如果不使用let关键字,那么重新给非mut的变量赋值会导致编译时错误
    • 而使用let声明的同名新变量,也是不可变的
    • 使用let声明的同名新变量,它的类型可以与之前不同
// const MAX_POINTS: u32 = 100_000;

fn main() {
    // const MAX_POINTS: u32 = 100_000;
    println!("Hello, world!");

    let mut x = 5;
    println!("The value of x is {}", x);

    x = 6;
    println!("The value of x is {}", x);

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

    let spaces = "    ";
    let spaces = spaces.len();
    println!("The length of spaces is {}", spaces);

   let guess: u32 = "42".parse().expect("Not a number");

    println!("The guess is {}", guess);
}

数据类型

  • 标量和复合类型
  • Rust是静态编译语言,在编译时必须知道所有变量的类型
    • 基于使用的值,编译器通常能够推断出它的具体类型
    • 但如果可能的类型比较多(例如把String转为整数的parse方法),就必须添加类型的标注,否则编译会报错

标量类型

  • 一个标量类型代表一个单个的值
  • Rust有四个主要的标量类型:
    • 整数类型
    • 浮点类型
    • 布尔类型
    • 字符类型

整数类型

  • 整数类型没有小数部分
  • 例如u32就是一个无符号的整数类型,占据32位的空间
  • 无符号整数类型以u开头
  • 有符号整数类型以i开头
  • Rust的整数类型列表:
    • 每种都分i和u,以及固定的位数
    • 有符号范围: -(2^n-1)到2^{n-1}-1
    • 无符号范围:0到2^n-1
length signed unsigned
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
arch isize usize

isize和usize类型

  • isize和usize类型的位数由程序运行的计算机的架构所决定:
    • 如果是64位计算机,那就是64位的
    • ...
  • 使用isize或usize的主要场景是对某种集合进行索引操作。

整数字面值

十进制、十六进制、八进制、二进制、byte

  • 除了byte类型外,所有的数值字面值都允许使用类型后缀。例如 57u8
  • 如果你不太清楚应该使用那种类型,可以使用Rust相应的默认类型
  • 整数的默认类型就是i32,总体上来说速度很快,即使在64位系统中

整数溢出

  • 例如:u8的范围是0-255,如果你把一个u8变量的值设为256,那么:
    • 调试模型下编译:Rust会检查整数溢出,如果发生溢出,程序在运行时就会panic
    • 发布模型下(--release)编译:Rust不会检查可能导致panic的整数溢出
    • 如果溢出发生:Rust会执行“环绕”操作:256变成0,257变成1... 但程序不会panic

浮点类型

  • Rust有两种基础的浮点类型,也就是含有小数部分的类型
    • f32,32位,单精度
    • f64,64位,双精度
  • Rust 的浮点类型使用了IEEE-754标准来表述
  • f64是默认类型,因为在现代CPU上f64和f32的速度差不多,而且精度更高。

数值操作

  • 加减乘除余等

布尔类型

  • Rust的布尔类型也有两个值:true 和 false
  • 一个字节大小
  • 符号是bool

字符类型

  • Rust语言中char类型被用来描述语言中最基础的单个字符
  • 字符类型的字面值使用单引号
  • 占用4字节大小
  • 是Unicode标量值,可以表示比ASCII多得多的字符内容:拼音、中日韩文、零长度空白字符、emoji表情等
    • U+0000 到 U+D7FF
    • U+E000 到 U+10FFFF
  • 但Unicode中并没有“字符”的概念,所以直觉上认为的字符也许与Rust中的概念并不相符
// const MAX_POINTS: u32 = 100_000;

fn main() {
    // const MAX_POINTS: u32 = 100_000;
    println!("Hello, world!");

    let mut x = 5;
    println!("The value of x is {}", x);

    x = 6;
    println!("The value of x is {}", x);

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

    let spaces = "    ";
    let spaces = spaces.len();
    println!("The length of spaces is {}", spaces);

    let guess: u32 = "42".parse().expect("Not a number");

    println!("The guess is {}", guess);

    // let x = 2.0; // f64

    // let y: f32 = 3.0; // f32

    // let sum = 5 + 10;

    // let difference = 95.5 - 4.3;

    // let product = 4 * 30;

    // let quotient = 56.7 / 32.2;

    // let reminder = 54 % 5;

    // let t = true;

    // let f: bool = false;

    // let x = 'z';
    // let y: char = 'a';
    // let z = '😘';
}

复合类型

  • 复合类型可以将多个值放在一个类型里
  • Rust提供了两种基础的复合类型:元组(Tuple)、数组

Tuple

  • Tuple 可以将多个类型的多个值放在一个类型里
  • Tuple 的长度是固定的:一旦声明就无法改变

创建Tuple

  • 在小括号里,将值用逗号分开
  • Tuple 中的每个位置都对应一个类型,Tuple中各元素的类型不必相同

获取Tuple的元素值

  • 可以使用模式匹配来解构(destructure)一个Tuple来获取元素的值

访问Tuple的元素

  • 在Tuple变量使用点标记法,后接元素的索引号
fn main() {

    let tup: (i32, f64, u8) = (500, 6.4, 1);

    println!("{}, {}, {}", tup.0, tup.1, tup.2);

    let (x, y, z) = tup;
    println!("{}, {}, {}", x, y, z);
}

数组

  • 数组也可以将多个值放在一个类型里
  • 数组中每个元素的类型必须相同
  • 数组的长度也是固定的

声明一个数组

  • 在中括号里,各值用逗号分开

数组的用处

  • 如果想让你的数据存放在stack(栈)上而不是heap(堆)上,或者想保证有固定数量的元素,这时使用数组更有好处
  • 数组没有Vector灵活
    • Vector和数组类似,它由标准款提供
    • Vector的长度可以改变
    • 如果你不确定应该用数组还是Vector,那么估计你应该用Vector

数组的类型

  • 数组的类型以这种形式表示:[类型; 长度] 例如:let a: [i32; 5] = [1, 2, 3, 4, 5];

另一种声明数组的方法

  • 如果数组的每个元素值都相同,那么可以在:
    • 在中括号里指定初始值
    • 然后是一个“;”
    • 最后是数组的长度
  • 例如:let a = [3; 5]; 它就相当于:let a = [3, 3, 3, 3, 3];

访问数组的元素

  • 数组是stack上分配的单个块的内存
  • 可以使用索引来访问数组的元素
  • 如果访问的索引超出了数组的范围,那么:
    • 编译会通过
    • 运行会报错(runtime时会panic)
    • Rust不会允许其继续访问相应地址的内存
fn main() {
    // let a = [1, 2, 3, 4, 5];

    let months = [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
    ];

    // let first = months[0];
    // let second = months[1];

    // let index = 15;
    let index = [12, 13, 14, 15];
    let month = months[index[1]];
    println!("{}", month);
}

总结

恭喜你迈出 Rust 编程的第一步!通过这篇教程,你已经轻松掌握了变量、数据类型和复合类型的基础知识,这些是构建 Rust 程序的基石。现在就打开编辑器,试着写几行 Rust 代码,感受它的强大吧!想更深入?关注我们的 Rust 教程系列,下一站带你探索更多精彩内容!

参考

  • 原创
  • 学分: 1
  • 分类: Rust
  • 标签: Rust 
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
寻月隐君
寻月隐君
0xE91e...6bE5
不要放弃,如果你喜欢这件事,就不要放弃。如果你不喜欢,那这也不好,因为一个人不应该做自己不喜欢的事。