百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Rust基础语法——数据类型和变量定义

zhezhongyun 2025-10-19 15:34 33 浏览


数据类型

Rust是一门静态类型语言,这意味着编译器在编译时需要知道所有变量的类型。

Rust的基本数据类型可以分为两大类:标量类型(Scalar Types)和复合类型(Compound Types),不允许类型自动转换。

一、标量类型

标量类型分为四种:整型、浮点型、布尔型、字符型

1、整型

整型就是没有小数点的数字,比如说 0,1,-1,-2,9999999 等,可以进一步分为 有符号整型无符号整型 两种。按照存储空间来说,整型可以进一步划分为 1字节、2字节、4字节、8字节、16字节。

isize和usize类型的位宽度取决于程序运行的平台:在64位平台上是64位,在32位平台上是32位。

整数溢出

如果我们尝试存储一个超出整数类型范围的值,在调试模式下编译时会导致程序崩溃(panic)

fn main() {
   let age:u8 = 255;
   // u8 只能存储 0 to 255 
   let weight:u8 = 256;   // 溢出值为 0
   let height:u8 = 257;   // 溢出值为 1
   let score:u8 = 258;    // 溢出值为 2
   println!("age is {} ",age);
   println!("weight is {}",weight);
   println!("height is {}",height);
   println!("score is {}",score);
}

运行代码,会有如下报错信息

error: literal out of range for u8
 --> src/main.rs:5:20
  |
5 |    let weight:u8 = 256;   // 溢出值为 0
  |                    ^^^
  |
  = note: #[deny(overflowing_literals)] on by default
error: literal out of range for u8
 --> src/main.rs:6:20
  |
6 |    let height:u8 = 257;   // 溢出值为 1
  |                    ^^^
error: literal out of range for u8
 --> src/main.rs:7:19
  |
7 |    let score:u8 = 258;    // 溢出值为 2
  |                   ^^^

为了避免整数溢出问题,Rust提供了几种处理方式:

使用checked_*方法:如果操作会导致溢出,返回None。
使用wrapping_*方法:即使发生溢出,也会执行环绕行为。
使用overflowing_*方法:返回操作的结果和一个表示是否发生溢出的布尔值。
使用saturating_*方法:在溢出时,将值限制在类型的最大值或最小值。浮点数类型

2、浮点型

浮点数类型表示有小数部分的数字。Rust有两种浮点数类型:f32(单精度浮点数,32位)和f64(双精度浮点数,64位)。f64是默认的浮点数类型,它的精度更高,在大多数情况下性能也更好。

示例如下:

fn main() {
   let result = 10.00;        // 默认是 f64 
   let interest:f32 = 8.35;
   let cost:f64 = 15000.600;  // 双精度浮点型
   println!("result value is {}",result);
   println!("interest is {}",interest);
   println!("cost is {}",cost);
}

3、布尔型

Rust的布尔值类型为bool,只有两个值:true和false。

示例如下:

let t = true;
let f: bool = false;

4、字符型

字符类型(char)表示单个Unicode字符,在Rust中用单引号'括起来。Rust的字符类型占4个字节,可以表示Unicode标量值,范围从U+0000到U+D7FF和U+E000到U+10FFFF。

示例如下:

fn main() {
   let special_character = '@'; 
   let alphabet:char = 'A';
   let emoji:char = ''; 
   println!("special character is {}",special_character);
   println!("alphabet is {}",alphabet);
   println!("emoji is {}",emoji);
}

二、复合类型

复合类型可以将多个值组合成一个类型。Rust有两种基本的复合类型:元组(Tuple)和数组(Array)。

1、元组

元组有着固定的长度。而且一旦定义,就不能再增长或缩小,元组的下标从 0 开始。使用一对小括号 () 把所有元素放在一起,元素之间使用逗号 , 分隔。

元组的定义语法格式如下:

let tuple_name:(data_type1,data_type2,data_type3) = (value1,value2,value3);

定义元组时也可以忽略数据类型。

let tuple_name = (value1,value2,value3);

如果显式指定了元组的数据类型,那么数据类型的个数必须和元组的个数相同,否则会报错,如果要输出元组中的所有元素,必须使用 {:?} 格式化符,因为元组是一个 复合类型,要输出复合类型的数据,必须使用 println!(“{:?}”, tuple_name)。

fn main() {
   let tuple:(i32,f64,u8) = (-325,4.9,22);
   println!("{:?}",tuple);
}

我们可以使用 元组名.索引数字 来访问元组中相应索引位置的元素。索引从 0 开始。

fn main() {
   let tuple:(i32,f64,u8) = (-325,4.9,22);
   println!("integer is :{:?}",tuple.0);
   println!("float is :{:?}",tuple.1);
   println!("unsigned integer is :{:?}",tuple.2);
}

元组也可以作为函数的参数。

fn main(){
   let b:(i32,bool,f64) = (110,true,10.9);
   print(b);
}
// 使用元组作为参数
fn print(x:(i32,bool,f64)){
   println!("Inside print method");
   println!("{:?}",x);
}

解构赋值 ( destructing ) 就是把元组 ( tuple ) 中的每一个元素按照顺序一个一个赋值给变量。

(age,is_male,cgpa) = (30,true,7.9);

赋值完成后,左边的各个变量的值为:

age      = 30;
is_male  = true;
cgpa     = 7.9;
fn main(){
   let b:(i32,bool,f64) = (30,true,7.9);
   print(b);
}
fn print(x:(i32,bool,f64)){
   println!("Inside print method");
   let (age,is_male,cgpa) = x; //assigns a tuple to 
   distinct variables
   println!("Age is {} , isMale? {},cgpa is 
   {}",age,is_male,cgpa);
}

2、数组

数组是将多个相同类型的值组合成一个复合类型的方式。与元组不同,数组中的所有元素必须是相同类型的。数组的长度也是固定的,一旦声明就不能改变。

fn main(){
   let arr = [10,20,30,40];
   println!("array is {:?}",arr);
   println!("array size is :{}",arr.len());
}

在数组初始化时,如果不想为数组中的每个元素指定值,我们可以为数组设置一个默认值,也就是使用 默认值初始化 语法。

当使用 默认值初始化 语法初始化数组时,数组中的每一个元素都被设置为默认值。

fn main() {
   let arr:[i32;4] = [-1;4];
   println!("array is {:?}",arr);
   println!("array size is :{}",arr.len());
}

len() 方法用于返回数组的长度,返回值是一个整型。

fn main() {
   let arr:[i32;4] = [-1;4];
   println!("array size is :{}",arr.len());
}

在其它语言中,一般使用 for 循环来遍历数组,Rust 语言也可以,只不过是使用 for 语句的变种 for … in .. 语句。for in 语法中的左闭右开法则。

fn main(){
   let arr:[i32;4] = [10,20,30,40];
   println!("array is {:?}",arr);
   println!("array size is :{}",arr.len());
   for index in 0..4 {
      println!("index is: {} & value is : {}",index,arr[index]);
   }
}

使用 iter() 函数为数组生成一个迭代器,可以使用 for in 语法来迭代数组。

fn main(){
   let arr:[i32;4] = [10,20,30,40];
   println!("array is {:?}",arr);
   println!("array size is :{}",arr.len());
   for val in arr.iter(){
      println!("value is :{}",val);
   }

如果要让数组的元素可以修改,就需要添加 mut 关键字。

fn main(){
   let mut arr:[i32;4] = [10,20,30,40];
   arr[1] = 0;
   println!("{:?}",arr);
}

使用传值方式将数组传递给函数做参数。函数对参数的任何修改都不会影响到原来的数组。

fn main() {
   let arr = [10,20,30];
   update(arr);
   println!("Inside main {:?}",arr);
}
fn update(mut arr:[i32;3]){
   for i in 0..3 {
      arr[i] = 0;
   }
   println!("Inside update {:?}",arr);
}

用引用方式将数组传递给函数做参数。函数对参数的任何修改都会影响到原来的数组。

fn main() {
   let mut arr = [10,20,30];
   update(&mut arr);
   println!("Inside main {:?}",arr);
}
fn update(arr:&mut [i32;3]){
   for i in 0..3 {
      arr[i] = 0;
   }
   println!("Inside update {:?}",arr);
}

声明数组时长度必须指定为整数字面量或者整数常量。如果数组长度是一个变量,则会报编译错误。

fn main() {
   let N: usize = 20;
   let arr = [0; N]; //错误: non-constant used with constant
   print!("{}",arr[10])
}

如果将 let 关键字修改为 const 关键字,编译就能通过。usize 是一个指针所占用的大小。它的实际大小取决于你编译程序的 cpu 体系结构。

fn main() {
   const N: usize = 20; 
   // 固定大小
   let arr = [0; N];
   print!("{}",arr[10])
}

变量定义

变量是编程中用于存储数据的容器,是对 内存 的标记。因为内存中存储的数据是有数据类型的,所以变量也是有数据类型的。变量的数据类型不仅用于标识内存中存储的数据类型,还用于标识内存中存储的数据的大小。同时也标识内存中存储的数据可以进行的操作。

一、变量命名规则

1、变量名中可以包含字母、数字和下划线。

2、变量名必须以字母或下划线开头,不能以 数字 开头。

3、变量名是区分大小写。

二、变量声明

使用 let 来声明变量,在第一次赋值之后,是不可变更不可重新赋值的,变成了只读状态。

在Rust中,变量默认是不可变的(immutable),这意味着一旦变量被赋值,就不能再改变它的值。这是Rust语言安全性的一个重要特性,可以防止意外修改变量值导致的错误。

fn main() {
   let fees = 25_000;
   println!("fees is {} ",fees);
   fees = 35_000;
   println!("fees changed is {}",fees);
}

编译上面这段代码,报错:

error[E0384]: re-assignment of immutable variable `fees`
 --> main.rs:6:3
   |
 3 | let fees = 25_000;
   | ---- first assignment to `fees`
...
 6 | fees=35_000;
   | ^^^^^^^^^^^ re-assignment of immutable variable
error: aborting due to previous error(s)

Rust 语言提供了 mut 关键字表示 可变更。 我们可以在变量名的前面加上 mut 关键字来告诉编译器这个变量是可以重新赋值的。

fn main() {
   let mut fees:i32 = 25_000;
   println!("fees is {} ",fees);
   fees = 35_000;
   println!("fees changed is {}",fees);
}

三、变量隐藏

在Rust中,我们可以在同一个作用域内声明一个与已存在变量同名的新变量,这被称为变量隐藏(Variable Shadowing)。新变量会隐藏旧变量,使旧变量在后续的代码中不可见:

let x = 5;
println!("x = {}", x); // 输出: x = 5

let x = x + 1; // 隐藏旧的x,创建一个新的x
println!("x = {}", x); // 输出: x = 6

let x = "hello"; // 再次隐藏x,类型可以不同
println!("x = {}", x); // 输出: x = hello

四、定义常量

常量(Constants)是绑定到一个名称且不允许改变的值。与不可变变量不同的是:

  1. 必须使用const关键字而不是let来声明,常量一旦定义就永远不可变更和重新赋值。
  2. 必须显式地指定类型。
  3. 可以在任何作用域内声明,包括全局作用域。
  4. 只能被设置为常量表达式,不能是函数调用的结果或其他在运行时计算的值。
  5. 不能出现同名常量,变量可以(隐藏/屏蔽)。
const MAX_POINTS: u32 = 100_000;

五、数字分隔符

为了方便阅读超大的数字,Rust 语言允许使用一个 虚拟的分隔符 也就是 下划线( _ ) 来对数字进行可读性分隔符。

比如为了提高 50000 的可读性,我们可以写成 50_000 。

Rust 语言会在编译时移除数字可读性分隔符_。

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...