从零开始学Rust:所有权(Ownership)机制精要

文章目录

  • 第四章:Ownership 所有权
    • 核心概念
    • 关键机制
    • 引用与借用(Reference & Borrowing)
      • 悬垂引用问题
        • 错误示例分析
        • 解决方案
        • 引用安全规则
    • 切片(Slice)
    • 内存安全保证

第四章:Ownership 所有权

Ownership is Rust’s most unique feature, and it enables Rust to make memory safety guarantees without needing a garbage collector.

核心概念

所有权三原则:

  • 每个值有且只有一个所有者
  • 所有权可转移(move)
  • 所有者离开作用域时值自动释放(drop)
  • Each value in Rust has a variable that’s called its owner.
  • There can only be one owner at a time.
  • When the owner goes out of scope, the value will be dropped.

内存管理:

  • 栈(Stack):固定大小数据,高效自动管理
  • 堆(Heap):动态大小数据,需显式分配

Example:

fn main() {let mut s = String::from("hello");s.push_str(", world!"); // push_str() appends a literal to a Stringprintln!("{}", s); // This will print `hello, world!`
}

Note: In C++, this pattern of deallocating resources at the end of an item’s lifetime is sometimes called Resource Acquisition Is Initialization (RAII). The drop function in Rust will be familiar to you if you’ve used RAII patterns.

关键机制

  • 移动语义(Move):

    • 赋值操作默认转移所有权(非浅拷贝)
    • 原变量随即失效,防止悬垂指针
    let s1 = String::from("hello");
    let s2 = s1;  // s1所有权转移至s2,s1失效
    

    If you’ve heard the terms shallow copy and deep copy while working with other languages, the concept of copying the pointer, length, and capacity without copying the data probably sounds like making a shallow copy. But because Rust also invalidates the first variable, instead of being called a shallow copy, it’s known as a move. In this example, we would say that s1 was moved into s2.
    在这里插入图片描述
    Rust will never automatically create “deep” copies of your data. Therefore, any automatic copying can be assumed to be inexpensive in terms of runtime performance.

  • 克隆(Clone):

    • 显式深度拷贝堆数据
    let s1 = String::from("hello");
    let s2 = s1.clone();  // 完整拷贝数据
    

    When you see a call to clone, you know that some arbitrary code is being executed and that code may be expensive. It’s a visual indicator that something different is going on.
    在这里插入图片描述

  • Copy trait:

    • 标量类型(整数、布尔值等)自动实现
    • 赋值时执行位拷贝而非所有权转移
    • 与Drop trait互斥

引用与借用(Reference & Borrowing)

  • 不可变引用:

    • 允许多个同时存在
    • 禁止修改数据
    fn calculate_length(s: &String) -> usize {s.len()
    }
    
  • 可变引用:

    • 独占性:同一作用域只能存在一个
    • 数据竞争预防
    fn change(s: &mut String) {s.push_str(", world");
    }
    

悬垂引用问题

悬垂引用(Dangling Reference)是指指针指向的内存已经被释放但指针仍然存在的情况,这是内存安全的重大威胁。

错误示例分析
fn dangle() -> &String {  // 尝试返回字符串引用let s = String::from("hello");  // 创建局部变量&s  // 返回局部变量的引用
}  // s离开作用域被释放,返回的引用变成悬垂指针

编译器会阻止这段代码编译,错误提示:

error[E0106]: missing lifetime specifier
解决方案
  1. 转移所有权
fn no_dangle() -> String {  // 直接返回String(转移所有权)let s = String::from("hello");s  // 所有权转移给调用者
}
  1. 使用静态生命周期
fn get_static_str() -> &'static str {"hello"  // 字符串字面量有'static生命周期
}
引用安全规则
  1. 可变性独占原则:
  • 任意时刻,一个数据要么:
    • 有唯一的可变引用(&mut T)
    • 或有多个不可变引用(&T)
  • 二者不可同时存在
  1. 生命周期保证:
  • 所有引用必须始终有效

  • 编译器通过生命周期检查确保:

    fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {if x.len() > y.len() { x } else { y }
    }
    

切片(Slice)

  • 字符串切片:
    • 安全视图,不获取所有权
    let s = String::from("hello world");let hello = &s[0..5];
    let world = &s[6..11];
    
  • 通用原则:
    • 编译时保证引用有效性
    • 自动边界检查防止越界访问

在这里插入图片描述

内存安全保证

所有权系统在编译期实现:

  • 自动内存回收(RAII模式)
  • 无数据竞争
  • 无悬垂指针
  • 零运行时开销

这套机制使Rust无需垃圾回收器即可保证内存安全,同时保持与C/C++相当的性能。

The concepts of ownership, borrowing, and slices ensure memory safety in Rust programs at compile time. The Rust language gives you control over your memory usage in the same way as other systems programming languages, but having the owner of data automatically clean up that data when the owner goes out of scope means you don’t have to write and debug extra code to get this control.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一旦懂得,有趣得紧1:词根tempt-(尝试)的两种解法

词根tempt-尝试 tempt vt.引诱&#xff1b;诱惑&#xff1b;怂恿&#xff1b;利诱&#xff1b;劝诱&#xff1b;鼓动 temptation n.引诱&#xff1b;诱惑 // tempt v.引诱 -ation 名词后缀 attempt v.&n.尝试&#xff0c;试图 // at- 加强 tempt 尝试contempt n.蔑视&am…

召唤数学精灵

1.召唤数学精灵 - 蓝桥云课 问题描述 数学家们发现了两种用于召唤强大的数学精灵的仪式&#xff0c;这两种仪式分别被称为累加法仪式 A(n) 和累乘法仪式 B(n)。 累加法仪式 A(n) 是将从1到 n 的所有数字进行累加求和&#xff0c;即&#xff1a; A(n)12⋯n 累乘法仪式 B(n) …

C语言实现查表8位SAE J1850 CRC

背景&#xff1a; 在做霍尔采集电流的时候&#xff0c;CSSV1500N 系列电流传感器通过can数据输出的报文需要做crc校验&#xff0c;嵌入式常用查表的方式&#xff0c;所以就问了下deepseek怎么算这个CRC. 以下是使用 查表法&#xff08;Lookup Table&#xff09; 在C语言中高效…

【UE5.3.2】初学1:适合初学者的入门路线图和建议

3D人物的动作制作 大神分析:3D人物的动作制作通常可以分为以下几个步骤: 角色绑定(Rigging):将3D人物模型绑定到一个骨骼结构上,使得模型能够进行动画控制。 动画制作(Animation):通过控制骨骼结构,制作出人物的各种动作,例如走路、跳跃、打斗等。 动画编辑(Ani…

mapreduce的工作原理

MapReduce 是 Hadoop 中实现分布式并行计算的核心框架&#xff0c;其工作原理基于“分而治之”的思想&#xff0c;将大规模数据处理任务分解为 Map&#xff08;映射&#xff09; 和 Reduce&#xff08;归约&#xff09; 两个阶段。 一、MapReduce 核心流程 1. Input 阶段 - 输…

换季推广不好做?DeepBI用一键托管的方式,让广告投放跑得快、准、稳

每年换季&#xff0c;尤其是春夏、秋冬交替的节点&#xff0c;都是电商平台上各类季节性商品扎堆上新的高峰期。无论是服饰鞋包、家居户外&#xff0c;还是母婴用品、美妆护肤&#xff0c;许多商品都有着强烈的“时间窗口效应”——一旦错过了热卖期&#xff0c;流量下滑迅速&a…

Qt5.14.2+Cmake使用mingw64位编译opencv4.5成功图文教程

​ 一、下载安装相关编译环境软件 1.1 Python3.8&#xff1a;安装路径:C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32 安装包&#xff1a;python3.8.exe 1.2 QT5.14.2&#xff1a;安装路径:C:\Qt\Qt5.14.2 1.3 opencv4.5&#xff1a;解压路径D:\o…

OpenBMC:BmcWeb 处理http请求3 字典树查找节点

OpenBMC:BmcWeb 处理http请求2 查找路由对象-CSDN博客 findRouteByPerMethod实际上是调用了perMethod.trie.find(url);来查找路由对象的 class Trie {struct FindResult{unsigned ruleIndex;std::vector<std::string> params;};FindResult findHelper(const std::string…

Openssl自签证书相关知识

1.前提 检查是否已安装 openssl $ which openssl /usr/bin/openssl 2.建立CA授权中心 2.1.生成ca私钥(ca-prikey.pem) 初始化 OpenSSL 证书颁发机构(CA)的序列号文件 在生成证书时,ca.srl 的初始序列号需正确初始化(如 01),否则可能导致证书冲突 这会将 01 显示在屏幕…

K个一组翻转链表--囊括半数链表题的思想

K 个一组翻转链表 这道算法题就是链表多个算法思想的结合&#xff0c;解决这一道leetcodehot100的链表题至少能做一半了 大概有一下几个点 1.链表定位 2.链表翻转 3.哨兵节点 4.链表合并 看看题目 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff…

Flutter敏感词过滤实战:基于AC自动机的高效解决方案

Flutter敏感词过滤实战&#xff1a;基于AC自动机的高效解决方案 在社交、直播、论坛等UGC场景中&#xff0c;敏感词过滤是保障平台安全的关键防线。本文将深入解析基于AC自动机的Flutter敏感词过滤实现方案&#xff0c;通过原理剖析实战代码性能对比&#xff0c;带你打造毫秒级…

UML中的用例图和类图

在UML&#xff08;统一建模语言&#xff09;中&#xff0c;**用例图&#xff08;Use Case Diagram&#xff09;和类图&#xff08;Class Diagram&#xff09;**是两种最常用的图表类型&#xff0c;分别用于描述系统的高层功能和静态结构。以下是它们的核心概念、用途及区别&…

深入解析:HarmonyOS Design设计语言的核心理念

深入解析&#xff1a;HarmonyOS Design设计语言的核心理念 在当今数字化迅速发展的时代&#xff0c;用户对操作系统的体验要求越来越高。华为的HarmonyOS&#xff08;鸿蒙操作系统&#xff09;应运而生&#xff0c;旨在为用户提供全场景、全设备的智慧体验。其背后的设计语言—…

Vue 类与样式

数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute&#xff0c;我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。但是&#xff0c;在处理比较复杂的绑定时&#xff0c;通过拼接生成字符串是麻烦且易…

Android 中获取颜色资源

在 Android 开发中&#xff0c;资源&#xff08;如字符串、颜色等&#xff09;通常存储在 res 文件夹中&#xff0c;并通过资源 ID 进行访问。资源 ID 是一个整型值&#xff0c;用于唯一标识资源&#xff0c;若需要将资源转换为整型值&#xff0c;通常是指获取资源 ID 或从资源…

Linux中的文件寻址

Linux的层级结构 在Linux中一切皆文件 其中 要注意在命令行中看实际选择写哪一种路径 相对路径 绝对路径名称的简写&#xff0c;省略了用户当前所在的系统位置此名称只有在管理当前所在系统目录中子文件时才能使用系统中不以/开有的文件名称都为相对路径在程序操作时会自动…

洛谷: P1825 [USACO11OPEN] Corn Maze S

原题链接:P1825 [USACO11OPEN] Corn Maze S - 洛谷 题目描述 This past fall, Farmer John took the cows to visit a corn maze. But this wasnt just any corn maze: it featured several gravity-powered teleporter slides, which cause cows to teleport instantly from…

探秘DeepSeek:开源AI领域的创新先锋

一、引言 在人工智能迅猛发展的当下&#xff0c;众多先进的模型如雨后春笋般涌现&#xff0c;而 DeepSeek 无疑是其中备受瞩目的一颗新星。它以独特的技术优势和广泛的应用场景&#xff0c;在 AI 领域崭露头角。 二、DeepSeek 的诞生与背景 DeepSeek 由来自广东省的中国企业…

Spring Boot启动流程

1. 启动类与main方法 入口点&#xff1a;Spring Boot应用通常有一个带有SpringBootApplication注解的主类&#xff0c;并包含一个public static void main(String[] args)方法。 SpringBootApplication是一个组合注解&#xff0c;包含了&#xff1a; Configuration: 标记该类为…

设计模式——设计模式理念

文章目录 参考&#xff1a;[设计模式——设计模式理念](https://mp.weixin.qq.com/s/IEduZFF6SaeAthWFFV6zKQ)参考&#xff1a;[设计模式——工厂方法模式](https://mp.weixin.qq.com/s/7tKIPtjvDxDJm4uFnqGsgQ)参考&#xff1a;[设计模式——抽象工厂模式](https://mp.weixin.…