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

Rust基础[part4]_基本类型,所有权

Rust基础[part4]_基本类型,所有权

Rust类型

概览

以下是整合后的 Rust 类型说明表格:

类型说明
i8i16i32i64i128u8u16u32u64u128给定位宽的有符号整数和无符号整数42-5i80x400u160o100i1620_922_789_888_000u64b'*'u8 字节字面量)
isizeusize与机器字(32 位或 64 位)一样大的有符号整数和无符号整数137-0b0101_0010isize0xffff_fc00usize
f32f64单精度 IEEE 浮点数和双精度 IEEE 浮点数1.618033.14f326.0221e23f64
bool布尔值truefalse
charUnicode 字符,32 位宽(4 字节)'*''\n''字''\x7f''\u{...}'(Unicode 转义)
(char, u8, i32)元组,允许混合类型('%', 0x7f, -1)
()“单元”(空元组)()
struct S { x: f32, y: f32 }具名字段型结构体S { x: 120.0, y: 209.0 }
struct T(i32, char);元组型结构体T (120, 'X')
struct E;单元型结构体,无字段E
enum Attend { OnTime, Late(u32) }枚举,或代数数据类型Attend::Late(5)Attend::OnTime
Box<Attend>Box:指向堆中值的拥有型指针Box::new(Late(15))
&i32&mut i32共享引用和可变引用:非拥有型指针,其生命周期不能超出引用目标&s.y&mut v
StringUTF-8 字符串,动态分配大小" ラーメン : ramen".to_string()
&strstr 的引用:指向 UTF-8 文本的非拥有型指针" そば : soba"&s[0..12]
[f64; 4][u8; 256]数组,固定长度,其元素类型都相同[1.0, 0.0, 0.0, 1.0][b' '; 256]
Vec<f64>向量,可变长度,其元素类型都相同vec![0.367, 2.718, 7.389]
&[u8]*mut [u8]对切片(数组或向量某一部分)的引用,包含指针和长度&v[10..20]&mut a[..]
Option<&str>可选值:或者为 None(无值),或者为 Some(v)(有值,其值为 vSome("Dr.")None
Result可能失败的操作结果:或者为成功值 Ok(v),或者为错误值 Err(e)Ok(4096)Err(Error::last_os_error())
&dyn Any&mut dyn Read特型对象,是对任何实现了一组给定方法的值的引用value as &dyn Any&mut file as &mut dyn Read
fn(&str) -> bool函数指针str::is_empty
(闭包类型没有显式书写形式)闭包`
x..=y序列1..=4

整型

大小有符号无符号
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
视架构而定isizeusize
pub fn print_int_show() {let integer: i32 = 2147483647; // 最大值let integer: i32 = -2147483648; // 最小值let integer: i32 = 0x1F; // 十六进制let integer: i32 = 0o17; // 八进制let integer: i32 = 0b1111_0000; // 二进制let integer: i32 = 1_000_000; // 使用下划线分隔数字let integer: u8 = b'A'; // 字符转换为整数
}

浮点型

浮点类型数数字,带有小数点,基本两种类型是:f32和f64

默认为f64,精度更高,速度基本和f32相同

但是一般在区块链应用中,一般都使用i128, 因为精度的问题

精度问题

精度问题,Rust 作为一门注重内存安全和性能的系统级编程语言,在处理数值精度时遵循明确的规则,但也存在一些需要开发者注意的潜在陷阱。

    assert_eq!(0.1 + 0.2, 0.3); // 浮点数相加 这里会failed
    println!("0.1 + 0.2 = {:x}", (abc.0 + abc.1).to_bits());println!("0.3 = {:x}", abc.2.to_bits());println!("0.1 + 0.2 = {:x}", (xyz.0 + xyz.1).to_bits());println!("0.3 = {:x}", xyz.2.to_bits());

结果,发现高精度的0.1 + 0.2 的结果和0.3的结果是不同的。

0.1 + 0.2 = 3e99999a
0.3 = 3e99999a
0.1 + 0.2 = 3fd3333333333334
0.3 = 3fd3333333333333

这就是精度问题。

Rust 对整数浮点数的类型后缀语法有细微差别:

  • 整数:类型后缀直接紧跟数值,无下划线
    例如:1u3242i640xFFu8
  • 浮点数:类型后缀与数值之间必须有下划线_)。
    例如:0.5_f323.14159_f64

NAN

NAN(Not a Number) , 用来定义如以下这个平方根,这种数学上未定义的结果。

pub fn nan_example() {let nan_value: f64 = (-1.1_f64).sqrt(); // 计算负数的平方根assert!(nan_value.is_nan()); // 检查是否为NaNprintln!("NaN: {}", nan_value);
}

布尔类型

占一个字节

pub fn boolean_example() {let t = true;let f: bool = false;println!("true: {}, false: {}", t, f);
}

字符

单引号去声明的,unicode字符也可以作为Rust的字符 ,占用四个字节

pub fn char_example() {let c: char = 'A';let emoji: char = '😊';// unicode字符也可以作为Rust的字符println!("char: {}, emoji: {}", c, emoji);
}

序列

包含需要加上=

pub fn _sequence_example() {let seq = 1..=5; // 包含5的范围for i in seq {println!("Sequence: {}", i);}
}

类型强转

as关键字用于在原始类型之间进行类型转换,不适用于复合类型,比如String或其他自定义类型

pub fn convert() {let a: i32 = 10;let b: f64 = a as f64; // 将i32转换为f64println!("Converted value: {}", b);let c: f64 = 3.14;let d: i32 = c as i32; // 将f64转换为i32println!("Converted value: {}", d);
}

练习

https://practice-zh.course.rs/basic-types/numbers.html

错题记录:
// 填空
use std::ops::{Range, RangeInclusive};
fn main() {assert_eq!((1..5), Range{ start: 1, end: 5 });assert_eq!((1..=5), RangeInclusive::new(1, 5));
}
// 填空,并解决错误
fn main() {// 整数加法assert!(1u32 + 2 == 3);// 整数减法assert!(1i32 - 2 == -1);assert!(1i8 - 2 == -1);assert!(3 * 50 == 150);assert!(9.6 / 3.2 - 3.0 < 1e-9); assert!(24 % 5 == 4);// 逻辑与或非操作assert!(true && false == false);assert!(true || false == true);assert!(!true == false);// 位操作println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101);println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101);println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101);println!("1 << 5 is {}", 1u32 << 5);println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2);
}

所有权

零开销内存回收的一种高效实现方式

Rust是一种系统编程语言,其设计目的是确保内存安全并防止数据竞争,而不依赖垃圾回收器。这种内存安全性主要通过所有权系统来进行实现。

为什么需要所有权?

在系统编程语言中,内存管理一直是核心挑战:

  • 手动管理(如 C/C++):开发者需手动分配和释放内存,易出现悬空指针、内存泄漏等问题。
  • 垃圾回收(如 Java/Go):自动回收不再使用的内存,但带来运行时开销和不可预测的停顿。

Rust 通过所有权系统在编译期解决内存安全问题,无需垃圾回收,同时保持高性能。

基本规则

  1. 每一个值都有所有者(owner);
  2. 在任一时刻,值都只有一个所有者;
  3. 当所有者离开作用域(scope),值会被丢弃(drop);

move语义

pub fn _ownership_example() {let s1: String = String::from("Hello");let s2: String = s1; // 转移所有权// println!("{}", s1); // 此处会报错,因为s1的所有权已转移drop(s2); // rust中可以手动释放资源,但通常不需要这样做,因为Rust会在变量超出作用域时自动释放资源; 注意s1这个时候已经是类似空指针的状态,也不需要去释放println!("{}", s2);
}

copy语义

基本数据类型

fn main() {let x = 5;let y = x;  // x 的值被复制到 yprintln!("x = {}, y = {}", x, y); // 两个变量都有效
}

练习

// 用两种方法打印成功s1 和s2的值let s1 = String::from("Hello, Rust!");let s2 = ownership::take_ownership(s1); //以下代码不能修改println!("{}", s1);println!("{}", s2);

第一种方法

fn main() {// 第一种方法let s1 = String::from("Hello, Rust!");let s2 = take_ownership(s1.clone()); // 使用clone方法复制s1//以下代码不能修改println!("{}", s1);println!("{}", s2);
}
pub fn take_ownership(s: String) -> String {s // 返回的是 s的克隆
}

第二种方法

fn main() {// 第二种方法let s1 = String::from("Hello, Rust!");let s2 = take_ownership(&s1); // 传递s1的引用//以下代码不能修改println!("{}", s1);println!("{}", s2);
}// 传入类型改为引用类型
pub fn take_ownership(s: &String) -> &String {println!("Taking ownership of: {}", s);&s // 返回s的引用
}

后面会详细讲到引用的用法

http://www.lryc.cn/news/589556.html

相关文章:

  • Java 集合 示例
  • 【Qt】插件机制详解:从原理到实战
  • redisson tryLock
  • HAProxy双机热备,轻松实现负载均衡
  • [Python] -实用技巧6-Python中with语句和上下文管理器解析
  • Hessian矩阵在多元泰勒展开中如何用于构造优化详解
  • 记一次POST请求中URL中文参数乱码问题的解决方案
  • LeetCode 1888. 使二进制字符串字符交替的最少反转次数
  • 整除分块练习题
  • 使用Spring Cloud LoadBalancer报错java.lang.IllegalStateException
  • AI助手指南:从零开始打造Python学习环境(VSCode + Lingma/Copilot + Anaconda + 效率工具包)
  • 学习秒杀系统-实现秒杀功能(商品列表,商品详情,基本秒杀功能实现,订单详情)
  • Sharding-JDBC 分布式事务实战指南:XA/Seata 方案解析(三)
  • 2HDMI/1DP转EDP/LVDS,支持4K,144HZ和240HZ.
  • LSA链路状态通告
  • 学习软件测试的第十六天
  • 项目进度跨地域团队协作困难,如何统一进度安排
  • 原来时间序列挖掘这么简单
  • 力扣73:矩阵置零
  • NW917NW921美光固态闪存NW946NW952
  • 游戏行业中的恶梦:不断升级的DDoS攻击
  • 【HarmonyOS】ArkUI-X 跨平台框架入门详解(一)
  • 3.正则化——新闻分类
  • 【stm32】新建工程
  • STM32裸机开发(中断,轮询,状态机)与freeRTOS
  • MyBatis与Spring整合优化实战指南:从配置到性能调优
  • Conda 核心命令快速查阅表
  • 系统编程是什么
  • 22-C#的委托简单使用-2
  • ai问答推荐企业排名优化?:五大企业核心竞争力全景对比