Rust 初体验2
变量类型
Rust 语言的变量数据类型,主要包括整型、浮点型、字符、布尔型、元组、数组、字符串、枚举、结构体和可变变量等。
fn main() { // 整型 let integer: i32 = 100; println!("整型: {}", integer); // 浮点型 let floating_point: f64 = 3.14; println!("浮点型: {}", floating_point); // 字符 let character: char = 'A'; println!("字符: {}", character); // 布尔型 let boolean: bool = true; println!("布尔型: {}", boolean); // 字符串 let string: String = String::from("Hello, Rust!"); println!("字符串: {}", string); // 数组 let array: [i32; 5] = [1, 2, 3, 4, 5]; println!("数组: {:?}", array); // 元组 let tuple: (i32, f64, String) = (10, 2.5, String::from("tuple")); println!("元组: {:?}", tuple); // 枚举 #[derive(Debug)]enum Color { Red, Green, Blue} let color: Color = Color::Red; println!("枚举: {:?}", color); // 结构体#[derive(Debug)] struct Person { name: String, age: u32 } let person: Person = Person { name: String::from("Alice"), age: 30 }; println!("结构体: {:?}", person); // 可变变量 let mut mutable_variable = 10; mutable_variable = 20; println!("可变变量: {}", mutable_variable);
}
所有权
Rust中每个值都有一个所有者。Rust 确保在变量离开作用域时值被清理。
fn main() { let s1 = String::from("hello"); let s2 = s1; // s1 的所有权转移到 s2,s1 不再有效println!("{}, world!", s2); // Okprintln!("{}, world!", s1); // Error
}
这一点与C语言不同,C语言中 s1 的值被复制到 s2 中,s1仍然有效。
#include <stdio.h>
int main() { char* s1 = "hello"; char* s2 = s1; // s1 的所有权转移到 s2,s1 不再有效printf("%s\n", s2); // Okprintf("%s\n", s1); // OKreturn 0;
}
Rust 中的变量分为两种:栈变量、堆变量。
栈变量存储在栈上,堆变量存储在堆上。栈变量的大小是固定的,而堆变量的大小是不固定的,需要动态分配内存。
Rust 中的变量默认存储在栈上,如果需要存储在堆上,可以使用 Box<T> 类型。
-
栈(Stack):局部变量、函数参数和函数返回值通常存储在栈上。这些变量具有明确的生命周期,通常与它们所在的作用域相关。当变量离开其作用域时,它们的内存会被自动释放。
-
堆(Heap):动态分配的数据,如使用Box、String、Vec等类型创建的变量,通常存储在堆上。这些变量具有更长的生命周期,并且由 Rust 的垃圾回收器管理。当没有任何引用指向堆上的数据时,垃圾回收器会释放该内存。
-
静态存储区:静态变量和常量存储在静态存储区。这些变量的生命周期是整个程序的执行期间,它们在程序开始执行时就被分配,并在程序结束时才被释放。
在 Rust 中,变量的内存存储方式主要受到它们的数据类型和所有权规则的影响。在前面的 Rust 代码中,s1 和 s2 都是 String 类型的变量,这意味着它们存储的是对堆上分配的字符串数据的引用。
图 1 图1 图1
当 s1 被创建时,Rust 会在堆上分配内存来存储字符串 “hello”,并将一个引用(指针)赋值给 s1。这个引用包含了指向堆上数据的地址信息。
图 2 图2 图2
当 s2 被创建并赋值为 s1 时,根据 Rust 的所有权转移规则, s2 现在拥有了原来 s1 所拥有的数据的所有权。此时,s1 不再拥有对这块内存的所有权,它变成了一个悬空引用(dangling reference),指向一个不再有效的内存地址。
在 图2 中,s1 悬空。s2 指向了堆上存储的字符串 “hello”。当 s2 离开作用域并被销毁时,Rust 垃圾回收机制会确保释放这块堆上分配的内存。
在Rust中,变量本身通常存储在栈上(对于局部变量),而它们指向的数据(对于堆上分配的类型)则存储在堆上。所有权转移确保了当引用离开作用域时,相关的内存能够被正确地释放,从而避免了内存泄漏。
为什么要有这种机制?
Rust中的变量都是通过所有权(ownership)来管理的,当一个变量离开其作用域时,其占用的内存将被释放。这样可以避免内存泄漏和悬空指针的问题。
内存泄漏的主要原因是在程序中分配内存,但忘记释放它。Rust中的变量在离开作用域时会自动释放其占用的内存,因此不会发生内存泄漏。
悬空指针是指一个指针指向的内存已经被释放,但指针仍然指向该内存地址。悬空指针会导致程序崩溃或产生其他错误。在Rust中,变量在离开作用域时会自动释放其占用的内存,因此不会发生悬空指针的问题。
当然,安全性和灵活性之间需要进行权衡。在某些情况下,手动管理内存可以减少内存分配和释放的开销,从而提高程序的性能。但在其他情况下,Rust的自动内存管理可能会导致额外的开销和复杂性。因此,需要根据具体情况进行选择。
相关文章:
Rust 初体验2
变量类型 Rust 语言的变量数据类型,主要包括整型、浮点型、字符、布尔型、元组、数组、字符串、枚举、结构体和可变变量等。 fn main() { // 整型 let integer: i32 100; println!("整型: {}", integer); // 浮点型 let floating_point: f64 3.1…...
vue-cil的watch函数详解
在Vue中,watch是一个非常有用的API,用于侦听一个响应式引用(例如由ref创建)或响应式对象(由reactive创建)的属性,并在值变化时执行回调函数。Vue 3的Composition API引入了这种侦听方式…...
堆排及时间复杂度分析
箴言: 初始阶段,不需要去纠结那一种更优美,非要找出那一种是最好的,其实能解决问题的就是好办法。 一,常见排序时间复杂度 冒泡快排归并堆排桶排时间O(n^2)O(nlogn)O(nlogn)O(nlogn)kn空间O(1)O(1)O(nlogn)O(1)kn 二ÿ…...
数据结构:双向链表
文章目录 1. 双向带头循环链表的结构2. 相关操作2.1 创建节点2.2 尾插2.3 头插2.4 打印2.5 尾删2.6 头删2.7 查找2.8 指定位置前/后插入2.9 删除指定位置的节点2.10 删除指定位置后的节点2.11 销毁链表 3.顺序表与链表区别 1. 双向带头循环链表的结构 与单链表不同的是…...
51单片机之数码管显示表白数字篇
朝菌不知晦朔 蟪蛄不知春秋 眼界决定境界 CSDN 请求进入专栏 是否进入《51单片机专栏》? 确定 目录 数码管的简介 数码管引脚定义 数码管的原理图 74HC245 代码实现 静态数码管的显示 动态数码管的显示 数码管实现表白画面 数码管的简介 L…...
代码随想录算法训练营DAY16 | 二叉树 (3)
一、LeetCode 104 二叉树的最大深度 题目链接:104.二叉树的最大深度https://leetcode.cn/problems/maximum-depth-of-binary-tree/ 思路:采用后序遍历递归求解。 class Solution {int ans 0;public int maxDepth(TreeNode root) {if(root null){retur…...
springboot(ssm大学生计算机基础网络教学系统 在线课程系统Java系统
springboot(ssm大学生计算机基础网络教学系统 在线课程系统Java系统 开发语言:Java 框架:springboot(可改ssm) vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mys…...
前端架构: 脚手架的开发流程和常用框架
脚手架的开发流程 脚手架的创建 $ npm init 脚手架的开发 分包 分包是指当我们一个脚手架比较复杂的时候,不可能把所有的js代码全部写在一个脚手架当中势必会把它建很多的不同的模块 package,通常我们会把它称之为一个分包的过程会和实际的这个项目一样…...
3.0 Hadoop 概念
本章着重介绍 Hadoop 中的概念和组成部分,属于理论章节。如果你比较着急可以跳过。但作者不建议跳过,因为它与后面的章节息息相关。 Hadoop 整体设计 Hadoop 框架是用于计算机集群大数据处理的框架,所以它必须是一个可以部署在多台计算机上…...
mysql 对于null字段排序处理
最近遇到一个需求 ,需要对一个报表的多个字段进行多字段复杂条件排序 排序字段为NULL时 Mysql对于排序字段为NULL时,有自身默认的排序规则,默认是认为null 值 是无穷小 ELECT id,script_id,last_modified,live_count,next_show FROM virtua…...
NLP_语言模型的雏形 N-Gram 模型
文章目录 N-Gram 模型1.将给定的文本分割成连续的N个词的组合(N-Gram)2.统计每个N-Gram在文本中出现的次数,也就是词频3.为了得到一个词在给定上下文中出现的概率,我们可以利用条件概率公式计算。具体来讲,就是计算给定前N-1个词时࿰…...
mac电脑flutter环境配置,解决疑难问题
准备工作 首先搭建flutter的环境需要使用到flutter的sdk,可以直接跳去官网下载:Choose your first type of app - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter,下载时要注意你电脑所使用的芯片是Intel的还是苹果的芯片。 下载好的…...
C++ bool 布尔类型
在C 中 bool类型占用1个字节长度,bool 类型只有两个取值,true 和 false,true 表示“真”,false 表示“假”。 需要注意的C中使用cout 打印的时候是没有true 和 false 的 只有0和1 ,这里0表示假,非0表示真 …...
DC-7靶机渗透详细流程
信息收集: 1.存活扫描: 由于靶机和kali都是nat的网卡,都在一个网段,我们用arp-scan会快一点: arp-scan arp-scan -I eth0 -l └─# arp-scan -I eth0 -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:dd:ee:6…...
提速MySQL:数据库性能加速策略全解析
提速MySQL:数据库性能加速策略全解析 引言理解MySQL性能指标监控和评估性能指标索引优化技巧索引优化实战案例 查询优化实战查询优化案例分析 存储引擎优化InnoDB vs MyISAM选择和优化存储引擎存储引擎优化实例 配置调整与系统优化配置调整系统优化优化实例 实战案例…...
Flink实战六_直播礼物统计
接上文:Flink实战五_状态机制 1、需求背景 现在网络直播平台非常火爆,在斗鱼这样的网络直播间,经常可以看到这样的总榜排名,体现了主播的人气值。 人气值计算规则:用户发送1条弹幕互动,赠送1个荧光棒免费…...
Compose | UI组件(十五) | Scaffold - 脚手架
文章目录 前言一、Scaffold脚手架简介二、Scaffold的主要组件三、如何使用Scaffold四、Compose中Scaffold脚手架的具体例子例子1:基本Scaffold布局例子2:带有Drawer的Scaffold布局例子3:带有Snackbar的Scaffold布局 总结 前言 Compose中的Sca…...
Vue-60、Vue技术router-link的replace属性
1、作用:控制路由跳转时操作浏览器历史记录的模式 2、浏览器的历史记录有两种写入方式:分别是push和replace,push是追加历史记录,replace是替换当前记录。路由跳转时候默认为push 3、如何开启replace模式: <router-link rep…...
Hive与Presto中的列转行区别
Hive与Presto列转行的区别 1、背景描述2、Hive/Spark列转行3、Presto列转行 1、背景描述 在处理数据时,我们经常会遇到一个字段存储多个值,这时需要把一行数据转换为多行数据,形成标准的结构化数据 例如,将下面的两列数据并列转换…...
探讨CSDN等级制度:博客等级、原力等级、创作者等级
个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
