当前位置: 首页 > news >正文

Rust 数据类型

文章目录

  • Rust 数据类型
    • 标量类型
      • 整数类型
        • 整数溢出
      • 浮点类型
      • 数值运算
      • 布尔类型
      • 字符类型
    • 复合类型
      • 元组类型
      • 数组类型
        • 访问数组元素
        • 非法访问数组元素

Rust 数据类型

在这里插入图片描述

在 Rust 中,每个值都有特定的数据类型,数据类型告诉 Rust 该如何处理这些数据。我们将介绍两类数据类型:标量类型和复合类型。

请注意,Rust 是静态类型语言,这意味着编译时必须知道所有变量的类型。编译器通常可以根据值和用法推断类型。但在某些情况下(比如将 String 转换为数字类型时),需要添加类型注解,例如:

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

如果没有 : u32 类型注解,Rust 会报如下错误,提示需要更多类型信息:

$ cargo buildCompiling no_type_annotations v0.1.0 (file:///projects/no_type_annotations)
error[E0284]: type annotations needed--> src/main.rs:2:9|
2 |     let guess = "42".parse().expect("Not a number!");|         ^^^^^        ----- type must be known at this point|= note: cannot satisfy `<_ as FromStr>::Err == _`
help: consider giving `guess` an explicit type|
2 |     let guess: /* Type */ = "42".parse().expect("Not a number!");|              ++++++++++++

更多信息可通过 rustc --explain E0284 查看。其他数据类型也有类似的类型注解。

标量类型

标量类型表示单一值。Rust 有四种主要的标量类型:整数、浮点数、布尔值和字符。你可能在其他语言中也见过这些类型。

整数类型

整数是不带小数部分的数字。我们在第 2 章用过 u32 类型,表示 32 位无符号整数(有符号类型以 i 开头)。下表展示了 Rust 内置的整数类型:

长度有符号无符号
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
架构相关isizeusize

有符号类型可表示负数,无符号类型只能表示正数。Rust 使用二进制补码存储有符号数。

每种有符号类型能存储的范围是 −(2ⁿ⁻¹) 到 2ⁿ⁻¹−1,无符号类型是 0 到 2ⁿ−1。例如,i8 范围是 −128 到 127,u8 范围是 0 到 255。

isizeusize 的大小取决于计算机架构(32 位或 64 位)。

整数字面量可以用多种形式表示:

字面量类型示例
十进制98_222
十六进制0xff
八进制0o77
二进制0b1111_0000
字节(u8)b’A’

如果不确定用哪种类型,Rust 默认使用 i32isizeusize 主要用于集合索引。

整数溢出

例如,u8 的范围是 0 到 255。如果赋值超出范围(如 256),在 debug 模式下会 panic;release 模式下会发生环绕(256 变为 0,257 变为 1)。依赖溢出行为是错误的。

Rust 提供了多种方法处理溢出:

  • wrapping_* 方法:始终环绕
  • checked_* 方法:溢出时返回 None
  • overflowing_* 方法:返回值和是否溢出的布尔值
  • saturating_* 方法:溢出时取最大或最小值

浮点类型

Rust 有两种浮点类型:f32f64,分别为 32 位和 64 位,默认是 f64。所有浮点类型都是有符号的,遵循 IEEE-754 标准。

示例:

fn main() {let x = 2.0; // f64let y: f32 = 3.0; // f32
}

数值运算

Rust 支持加、减、乘、除、取余等基本运算。整数除法向零取整。

fn main() {let sum = 5 + 10;let difference = 95.5 - 4.3;let product = 4 * 30;let quotient = 56.7 / 32.2;let truncated = -5 / 3; // 结果为 -1let remainder = 43 % 5;
}

布尔类型

Rust 的布尔类型为 bool,只有 truefalse 两个值,占 1 字节。

fn main() {let t = true;let f: bool = false; // 显式类型注解
}

布尔值主要用于条件表达式(如 if)。

字符类型

Rust 的 char 类型用于表示单个字符,4 字节,支持 Unicode 标量值。

fn main() {let c = 'z';let z: char = 'ℤ';let heart_eyed_cat = '😻';
}

字符字面量用单引号。char 能表示多种字符,包括表情、汉字等。

复合类型

复合类型可以将多个值组合成一个类型。Rust 有两种原生复合类型:元组和数组。

元组类型

元组可以将不同类型的多个值组合在一起,长度固定。

fn main() {let tup: (i32, f64, u8) = (500, 6.4, 1);
}

可以使用模式匹配解构元组:

fn main() {let tup = (500, 6.4, 1);let (x, y, z) = tup;println!("The value of y is: {y}");
}

也可以通过索引访问元组元素:

fn main() {let x: (i32, f64, u8) = (500, 6.4, 1);let five_hundred = x.0;let six_point_four = x.1;let one = x.2;
}

空元组 () 被称为单元类型,表示空值或空返回类型。

数组类型

数组用于存储相同类型、固定长度的多个值。

fn main() {let a = [1, 2, 3, 4, 5];
}

数组适合需要固定数量元素且数据分配在栈上的场景。更灵活的可变长度集合请使用 vector。

数组类型写法:

let a: [i32; 5] = [1, 2, 3, 4, 5];

也可以用相同值初始化:

let a = [3; 5]; // 等价于 [3, 3, 3, 3, 3]
访问数组元素

通过索引访问数组元素:

fn main() {let a = [1, 2, 3, 4, 5];let first = a[0];let second = a[1];
}
非法访问数组元素

如果访问越界(如索引为 10),程序会 panic:

use std::io;fn main() {let a = [1, 2, 3, 4, 5];println!("Please enter an array index.");let mut index = String::new();io::stdin().read_line(&mut index).expect("Failed to read line");let index: usize = index.trim().parse().expect("Index entered was not a number");let element = a[index];println!("The value of the element at index {index} is: {element}");
}

如果输入超出范围,程序会报错并退出:

thread 'main' panicked at src/main.rs:19:19:
index out of bounds: the len is 5 but the index is 10

Rust 在运行时检查索引是否合法,防止非法内存访问。这体现了 Rust 的内存安全原则。

代码示例如下:

fn main() {// 整数let a = 10; // i32let b: i64 = 20; // i64// 打印整数println!("Integer a: {}, b: {}", a, b);// 浮点数let x = 2.0; // f64let y: f32 = 3.0; // f32// 打印浮点数println!("Float x: {}, y: {}", x, y);// 数值类型转换let int_to_float = a as f64; // i32 转 f64let float_to_int = y as i32; // f32 转 i32// 打印转换结果println!("Converted int to float: {}, Converted float to int: {}", int_to_float, float_to_int);// 数值运算let sum = 5 + 10;let difference = 95.5 - 4.3;let product = 4 * 30;let quotient = 56.7 / 32.2;let truncated = -5 / 3; // 结果为 -1let remainder = 43 % 5;// 打印数值运算结果println!("Sum: {}, Difference: {}, Product: {}, Quotient: {}, Truncated: {}, Remainder: {}", sum, difference, product, quotient, truncated, remainder);// 布尔值let is_active = true; // boollet is_valid: bool = false; // bool// 字符let c = 'A'; // charlet d: char = 'Z'; // char    let z: char = 'ℤ';let heart_eyed_cat = '😻';// 打印字符println!("Character c: {}, d: {}, z: {}, heart_eyed_cat: {}", c, d, z, heart_eyed_cat);// 字符串let s = "Hello, world!"; // &strlet t: String = String::from("Hello, Rust!"); // String// 元组let tuple = (1, 2.5, 'c'); // (i32, f64, char)let (x1, y1, z1) = tuple; // 解构元组// 数组let arr = [1, 2, 3, 4, 5]; // [i32; 5]let arr2: [f64; 3] = [1.0, 2.0, 3.0]; // [f64; 3]// 切片let slice = &arr[1..4]; // &[i32]let slice2: &[f64] = &arr2[0..2]; // &[f64]// 枚举enum Direction {Up,Down,Left,Right,}let dir = Direction::Up; // 使用枚举// 结构体struct Point {x: f64,y: f64,}let p = Point { x: 1.0, y: 2.0 }; // 创建结构体实例// 使用结构体println!("Point coordinates: ({}, {})", p.x, p.y);// 使用枚举match dir {Direction::Up => println!("Moving up"),Direction::Down => println!("Moving down"),Direction::Left => println!("Moving left"),Direction::Right => println!("Moving right"),}// 打印基本数据类型println!("Integer a: {}, b: {}", a, b);println!("Float x: {}, y: {}", x, y);println!("Boolean is_active: {}, is_valid: {}", is_active, is_valid);println!("Character c: {}, d: {}", c, d);println!("String s: {}, t: {}", s, t);println!("Tuple values: ({}, {}, {})", x1, y1, z1);println!("Array values: {:?}", arr);println!("Array2 values: {:?}", arr2);println!("Slice values: {:?}", slice);println!("Slice2 values: {:?}", slice2);// 结束程序println!("Program finished successfully.");
}

运行结果如下:

Integer a: 10, b: 20
Float x: 2, y: 3
Converted int to float: 10, Converted float to int: 3
Sum: 15, Difference: 91.2, Product: 120, Quotient: 1.7608695652173911, Truncated: -1, Remainder: 3
Character c: A, d: Z, z: ℤ, heart_eyed_cat: 😻
Point coordinates: (1, 2)
Moving up
Integer a: 10, b: 20
Float x: 2, y: 3
Boolean is_active: true, is_valid: false
Character c: A, d: Z
String s: Hello, world!, t: Hello, Rust!
Tuple values: (1, 2.5, c)
Array values: [1, 2, 3, 4, 5]
Array2 values: [1.0, 2.0, 3.0]
Slice values: [2, 3, 4]
Slice2 values: [1.0, 2.0]
Program finished successfully.

相关文章:

  • 物联网数据归档之数据存储方案选择分析
  • Agentic Workflow是什么?Agentic Workflow会成为下一个AI风口吗?
  • ES6 Promise 状态机
  • 从 iPhone 备份照片: 保存iPhone图片的5种方法
  • https(SSL)证书危机和可行的解决方案
  • Docker 插件生态:从网络插件到存储插件的扩展能力解析
  • 大数据-276 Spark MLib - 基础介绍 机器学习算法 Bagging和Boosting区别 GBDT梯度提升树
  • SQLite详细解读
  • C++ Learning string类模拟实现
  • FastMCP:构建 MCP 服务器和客户端的高效 Python 框架
  • 【Linux】线程互斥
  • 互联网三高架构 一
  • Python Day41学习(日志Day8复习)
  • Ajax技术分析方法全解:从基础到企业级实践(2025最新版)
  • HTTP Error 400 Bad request 问题分析解决
  • backend 服务尝试连接 qdrant 容器,但失败了,返回 502 Bad Gateway 问题排查
  • 为什么 uni-app 开发的 App 没有明显出现屏幕适配问题Flutter 开发的 App 出现了屏幕适配问题
  • 无人机避障——感知部分(Ubuntu 20.04 复现Vins Fusion跑数据集)胎教级教程
  • 网络安全厂商F5推出AI Gateway,化解大模型应用风险
  • 车载雷达:超声波雷达、毫米波雷达、激光雷达相关技术场景介绍和技术比较
  • 永康建设网站/培训
  • 网站怎么做最省钱/昆山网站建设推广
  • 无锡企业网站公司/最近在线直播免费观看
  • 长春建站价格/提高销售的10种方法
  • 阿里云企业网站备案/bt磁力搜索神器
  • 一个网站域名的组成/宣传网站有哪些