Rust 的智能指針

在 Rust 中,智能指針是一種特殊的數據結構,它不僅存儲數據的地址,還提供了額外的功能,如自動內存管理、引用計數等。智能指針在 Rust 中非常重要,因為它們幫助開發者管理內存,同時保持代碼的安全性和效率。本文將介紹幾種常見的智能指針,并通過實例展示它們的使用方法和區別。

1. Box<T>:堆分配

Box<T> 是 Rust 中最基本的智能指針,用于在堆上分配內存。它允許你在堆上存儲數據,并通過指針訪問這些數據。Box<T> 的主要用途是分配大型數據結構,避免在棧上占用過多空間。

示例代碼

use std::ops::Deref;// 定義一個 Person trait
trait Person {fn get_name(&self) -> String;
}// 定義一個 Employee 結構體
struct Employee {name: String,
}// 實現 Employee 的構造函數
impl Employee {fn new(name: String) -> Self {Self { name }}
}// 實現 Person trait 為 Employee
impl Person for Employee {fn get_name(&self) -> String {self.name.clone()}
}fn main() {// 使用 Box 在堆上分配一個 Employee 實例let person_ref: Box<dyn Person> = Box::new(Employee::new(String::from("Alice")));// 調用 get_name 方法并打印結果println!("{:#?}", person_ref.get_name());// 使用 Deref trait 自動解引用 Boxprint_name(person_ref.deref());// 另一種解引用方式print_name(&*person_ref);// 在堆上分配一個整數 10let age = Box::new(10);// 獲取 age 的不可變引用let age_ref = &age;// 調用 print_age 函數print_age(age_ref);
}// 定義一個函數,接受一個不可變引用并打印年齡
fn print_age(age: &u8) {println!("age is {}", age);
}// 定義一個函數,接受一個 Person trait 的不可變引用并打印名字
fn print_name(person: &dyn Person) {println!("name is {}", person.get_name());
}

代碼講解

  • Box<dyn Person>:創建一個動態類型 PersonBox,存儲一個 Employee 實例。
  • person_ref.deref():使用 Deref trait 自動解引用 Box,獲取內部的 Employee 引用。
  • &*person_ref:另一種解引用方式,* 操作符解引用 Box& 獲取引用。
  • Box::new(10):在堆上分配一個整數 10,并返回一個 Box 智能指針。

2. Cell<T>RefCell<T>:內部可變性

Cell<T>RefCell<T> 提供了內部可變性,允許你在不可變引用的情況下修改數據。Cell<T> 適用于 Copy 類型,而 RefCell<T> 適用于任意類型。

示例代碼

use std::cell::{Cell, RefCell};fn main() {// 使用 Cell 創建一個存儲字符串的智能指針let name = Cell::new(String::from("Alice"));// 使用 take 方法取出 Cell 中的值,并將其替換為 Noneprintln!("Hello, {}!", name.take());// 使用 set 方法將 Cell 中的值設置為 "Bob"name.set(String::from("Bob"));println!("Hello, {}!", name.take());// 使用 replace 方法將 Cell 中的值替換為 "Carol"name.replace(String::from("Carol"));println!("Hello, {}!", name.take());// 使用 RefCell 創建一個存儲字符串的智能指針let name = RefCell::new(String::from("Alice"));// 使用 borrow_mut 獲取 RefCell 的可變引用并修改內部值name.borrow_mut().push_str("6666");// 使用 borrow 獲取 RefCell 的不可變引用并打印內部值println!("Hello, {}!", name.borrow());
}

代碼講解

  • Cell::new(String::from("Alice")):創建一個 Cell,存儲一個字符串 "Alice"
  • name.take():取出 Cell 中的值,并將其替換為 None
  • name.set(String::from("Bob")):將 Cell 中的值設置為 "Bob"
  • RefCell::new(String::from("Alice")):創建一個 RefCell,存儲一個字符串 "Alice"
  • name.borrow_mut():獲取 RefCell 的可變引用,允許修改內部值。
  • name.borrow():獲取 RefCell 的不可變引用,用于讀取內部值。

3. Rc<T>:引用計數

Rc<T> 是一個引用計數的智能指針,允許多個所有者共享對同一數據的所有權。當最后一個 Rc<T> 被銷毀時,數據也會被自動銷毀。

示例代碼

use std::rc::Rc;// 定義一個 User 結構體
#[derive(Debug)]
struct User {name: Rc<String>,
}// 定義一個 Employee 結構體
#[derive(Debug)]
struct Employee {name: Rc<String>,
}fn main() {// 使用 Rc 創建一個存儲字符串的智能指針let name = Rc::new(String::from("Alice"));// 克隆 Rc 智能指針,增加引用計數let user = User {name: Rc::clone(&name),};println!("{:#?}", user);// 克隆 Rc 智能指針,增加引用計數let employee = Employee {name: Rc::clone(&name),};println!("{:#?}", employee);
}

代碼講解

  • Rc::new(String::from("Alice")):創建一個 Rc 智能指針,存儲一個字符串 "Alice"
  • Rc::clone(&name):克隆 Rc 智能指針,增加引用計數。
  • User { name: Rc::clone(&name) }:創建一個 User 實例,共享 Rc 智能指針。
  • Employee { name: Rc::clone(&name) }:創建一個 Employee 實例,共享 Rc 智能指針。

智能指針的區別

  1. Box<T>

    • 用于堆分配,適合大型數據結構。
    • 不提供內部可變性,解引用后獲取不可變引用。
  2. Cell<T>

    • 提供內部可變性,適用于 Copy 類型。
    • 通過 setreplace 方法修改內部值。
  3. RefCell<T>

    • 提供內部可變性,適用于任意類型。
    • 通過 borrow_mut 獲取可變引用,通過 borrow 獲取不可變引用。
  4. Rc<T>

    • 提供引用計數,允許多個所有者共享數據。
    • 通過 Rc::clone 增加引用計數,當最后一個 Rc 被銷毀時,自動銷毀數據。

總結

Rust 的智能指針提供了強大的內存管理和所有權控制功能。Box<T> 適用于堆分配,Cell<T>RefCell<T> 提供內部可變性,而 Rc<T> 用于共享所有權。通過這些智能指針,你可以編寫更安全、更高效的 Rust 代碼。希望本文能幫助你更好地理解 Rust 的智能指針及其使用方法!如果你有任何問題或建議,歡迎在評論區留言。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86316.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86316.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86316.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis RDB 持久化:原理、觸發方式與優缺點全解析

引言 作為 Redis 最經典的持久化機制之一&#xff0c;RDB&#xff08;Redis DataBase&#xff09;憑借高效的快照生成能力和快速的恢復速度&#xff0c;一直是開發者的心頭好。但很多人對它的底層原理、觸發時機和適用場景仍存在疑惑。今天咱們就對RDB進行全解析&#xff0c;幫…

設計模式精講 Day 12:代理模式(Proxy Pattern)

【設計模式精講 Day 12】代理模式&#xff08;Proxy Pattern&#xff09; 文章內容 在軟件開發中&#xff0c;代理模式是一種常見的結構型設計模式&#xff0c;它通過引入一個代理對象來控制對真實對象的訪問。這種模式不僅能夠增強系統的安全性、靈活性和可擴展性&#xff0c…

企業級知識庫私有化部署:騰訊混元+云容器服務TKE實戰

1. 背景需求分析 在金融、醫療等數據敏感行業&#xff0c;企業需要構建完全自主可控的知識庫系統。本文以某證券機構智能投研系統為原型&#xff0c;演示如何基于騰訊混元大模型與TKE容器服務實現&#xff1a; 千億級參數模型的私有化部署金融領域垂直場景微調高并發低延遲推…

Qt事件系統詳解

一、Qt事件系統概述 Qt事件系統是Qt框架中處理用戶輸入、窗口交互、定時器、異步操作等機制的核心。所有事件均繼承自QEvent類&#xff0c;并通過事件循環&#xff08;Event Loop&#xff09;分發到目標對象。 事件系統基本概念 事件(Event)&#xff1a;描述應用程序內部或外…

CPU性能篇-系統中出現大量不可中斷進程和僵尸進程怎么辦? Day 05

在上下文切換的文章中&#xff0c;學習并分析了系統 CPU 使用率高的問題&#xff0c;剩下的等待 I/O 的 CPU 使用率&#xff08;以下簡稱為 iowait&#xff09;升高&#xff0c;也是最常見的一個服務器性能問題。今天就來看一個多進程 I/O 的案例&#xff0c;并分析這種情況。 …

ASP.NET Core + Jenkins 實現自動化發布

一、安裝Jenkins 我這邊服務器是Linux CentOS 7 &#xff0c;使用SSH 登錄云服務器后&#xff0c;輸入以下命令安裝jenkins. sudo wget -O /etc/yum.repos.d/jenkins.repo \https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/red…

Java項目RestfulAPI設計最佳實踐

大家好&#xff0c;我是鋒哥。今天分享關于【Java項目RestfulAPI設計最佳實踐】面試題。希望對大家有幫助&#xff1b; Java項目RestfulAPI設計最佳實踐 超硬核AI學習資料&#xff0c;現在永久免費了&#xff01; 設計一個高效、易維護的 Java 項目中的 RESTful API 涉及到一…

FANUC機器人教程:用戶坐標系標定及其使用方法

目錄 概述 工作站創建 任務描述 用戶坐標系標定方法 用戶坐標系標定操作 用戶坐標系手動測試 用戶坐標系在程序中的應用 用戶坐標系選擇指令介紹 機器人示教編程 仿真運行 仿真案例資源下載 概述 FANUC機器人的用戶坐標系&#xff0c;是用戶對每個作業空間定義的直…

動態庫與靜態庫【Linux】

程序編譯過程 源代碼(.cpp) → 預處理(.i) → 編譯(.s) → 匯編(.o) → 鏈接(可執行文件) g -o main.i -E main.cpp 參數說明&#xff1a; 參數功能輸出文件類型-E僅預處理.i-S預處理 編譯.s-c預處理 編譯 匯編.o無完整流程&#xff08;預處理→編譯→匯編→鏈接&…

MySQL MHA 故障轉移-VIP

MHA故障轉移-VIP #手工在主庫添加VIP ifconfig ens33:1 192.168.80.200/24配置VIP腳本 vim /usr/local/bin/master_ip_failoverchmod x /usr/local/bin/#!/usr/bin/env perl use strict; use warnings FATAL > all;use Getopt::Long;my ( $command, $ssh_user, $orig_mast…

Elasticsearch索引字段的類型

在 Elasticsearch 中&#xff0c;索引字段的類型&#xff08;即 Mapping 中的字段類型&#xff09;對搜索和存儲性能影響很大。下面是各種常用數據類型的用途及推薦使用場景總結&#xff1a; 1. keyword 類型&#xff08;精確匹配&#xff09; 適合數據&#xff1a; 不需要分詞…

kubernetes證書續簽-使用kubeadm更新證書(下)

#作者&#xff1a;任少近 文章目錄 查看kubelet證書查看kubelet當前所使用的證書 更換 node上的kubelet證書生成node1所需要的kubelet.conf文件生成node2所需要的kubelet.conf文件查看csr 更新 ~/.kube/config 文件重啟相關組件 查看kubelet證書 以上少了kubelet的證書&#…

AI智能體長期記憶系統架構設計:從認知模型到生產實踐

1 長期記憶:AI智能體的認知基石 1.1 人類記憶與AI記憶的類比 #mermaid-svg-VIPKAFe7VgN4UHFA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-VIPKAFe7VgN4UHFA .error-icon{fill:#552222;}#mermaid-svg-VIPKAFe7V…

快速上手:利用音頻大模型與Java提取視頻文案

文章目錄 1、前言2、需求說明2.1 需求說明2.2 數據準備 3、功能實現3.1 使用視頻理解大模型能力3.1.1 三方平臺視頻在線鏈接解析3.1.2 三方平臺視頻內網鏈接解析3.1.3 三方平臺視頻轉存本地服務 3.2 使用音頻識別大模型能力3.2.1 三方平臺視頻在線鏈接解析3.2.2 三方平臺視頻詳…

LLM復雜記憶存儲-多會話隔離案例實戰

導讀&#xff1a;在多用戶并發的對話系統中&#xff0c;會話隔離問題往往成為開發者面臨的技術難題。當數千個用戶同時與AI助手交互時&#xff0c;如何確保每個用戶的對話歷史完全獨立&#xff0c;避免數據混淆和隱私泄露&#xff1f; 本文深入剖析了基于RunnableWithMessageHi…

【PX4-AutoPilot教程-TIPS】PX4系統命令行控制臺ConsolesShells常用命令(持續更新)

PX4系統命令行控制臺 Consoles & Shells 常用命令 查看每個應用程序的堆棧使用情況獲取所有可用命令和APP的列表應用程序啟動、停止和狀態查詢查看本地文件系統查看剩余的可用RAM查看工作隊列中正在運行的內容以及運行速率查看特定的uORB話題調試uORB話題進行模式切換和故障…

國內優秀wordpress主題推薦

在國內&#xff0c;WordPress 主題市場雖然不如國外那樣龐大&#xff0c;但依然有許多優秀且適合中國用戶需求的主題。以下是一些經過評估和推薦的國內優秀WordPress主題&#xff0c;涵蓋不同類型的網站需求&#xff0c;如博客、企業官網、資源站、社區論壇等。 WP漢主題 WP漢…

第 6 章:進階話題

第 6 章&#xff1a;進階話題 過擬合vs欠擬合&#xff1a;模型復雜度和泛化能力的關系 在前面的章節中&#xff0c;我們已經學習了神經網絡的基礎知識、常見架構和基本訓練流程。然而&#xff0c;在實際的深度學習項目中&#xff0c;僅僅掌握這些基礎知識是不夠的。我們還需要…

4.2_1樸素模式匹配算法

知識總覽&#xff1a; 什么是字符串的模式匹配&#xff1a; 主串&#xff1a;想從該串獲取結果的串 模式串&#xff1a;想搜索的內容&#xff0c;不一定在主串中能搜到&#xff0c;子串一定能在主串中搜到 字符串模式匹配&#xff1a;在主串找模式串并返回找到的第一個模式串…

華為云Flexus+DeepSeek征文|華為云ModelArts搭建Dify-LLM應用開發平臺(AI智能選股大模型)

前言 在當今數字化時代&#xff0c;人工智能&#xff08;AI&#xff09;技術在金融領域的應用愈發廣泛&#xff0c;其中 AI 智能選股大模型備受關注。為了構建高效且精準的 AI 智能選股大模型&#xff0c;選擇合適的開發平臺和工具至關重要。華為云 ModelArts 作為一款面向 AI …