結構體字段能否單獨加 mut

你問的這個問題在 Rust 里很常見:


一、結構體字段能否單獨加 mut

1. 結構體字段能否單獨加 mut

不能。Rust 中,mut 是用來修飾變量綁定的,可變性是綁定的屬性,而不是結構體字段本身的屬性。

你不能寫:

let user1 = User {mut username: String::from("user1"),  // ? 語法錯誤email: String::from("user1@example.com"),sign_in_count: 1,active: true,
};

2. 結構體實例的可變性

  • 如果你希望修改結構體里的字段,必須讓整個結構體實例是可變的:

let mut user1 = User {username: String::from("user1"),email: String::from("user1@example.com"),sign_in_count: 1,active: true,
};// 修改字段
user1.username = String::from("new_user1");
  • 綁定為不可變(沒有 mut),那么所有字段都是不可變的,即使字段本身的數據類型是可變的。


3. 字段類型本身是可變的?

  • 結構體字段的類型本身是否可變,取決于字段的類型,比如用 CellRefCellMutexRwLock 等可以實現內部可變性。

  • 例如:

use std::cell::RefCell;struct User {username: RefCell<String>,email: String,sign_in_count: u64,active: bool,
}let user1 = User {username: RefCell::new(String::from("user1")),email: String::from("user1@example.com"),sign_in_count: 1,active: true,
};// 即使 user1 是不可變綁定,也能修改 username
user1.username.replace(String::from("new_user1"));

4. 總結

  • mut 修飾的是變量綁定本身,不能單獨修飾結構體字段。

  • 想修改結構體字段,必須綁定結構體實例為 mut

  • 需要對某些字段單獨內部可變,需用到內部可變性類型(Cell, RefCell 等)。


如果你想,我可以幫你寫完整示例代碼說明不同場景。

二、CellRefCellMutexRwLock 的簡單介紹和代碼示例和區別

好的!下面是 CellRefCellMutexRwLock 的簡單介紹和代碼示例,幫助你理解它們的區別和使用場景。


1. Cell<T>

  • 特點:提供內部可變性,允許在不可變引用中修改存儲的值。

  • 限制:只支持實現了 Copy trait 的類型。

  • 線程限制:只能在單線程環境使用(不實現 Sync)。

use std::cell::Cell;struct MyStruct {value: Cell<i32>,
}fn main() {let s = MyStruct { value: Cell::new(10) };// 即使 s 是不可變的,也能修改 values.value.set(20);println!("value = {}", s.value.get());
}

2. RefCell<T>

  • 特點:提供“運行時可變借用檢查”,支持在不可變引用中可變訪問。

  • 限制:適用于單線程,動態借用規則在運行時檢查(借用沖突時會 panic)。

  • 用途:復雜數據結構中需要內部可變性時。

use std::cell::RefCell;struct MyStruct {value: RefCell<String>,
}fn main() {let s = MyStruct { value: RefCell::new(String::from("hello")) };// 獲取可變引用,修改內部數據s.value.borrow_mut().push_str(" world");// 讀取數據println!("value = {}", s.value.borrow());
}

3. Mutex<T>

  • 特點:線程安全的互斥鎖,保證多線程環境下數據的獨占訪問。

  • 用途:多線程并發訪問時保護共享資源。

use std::sync::Mutex;
use std::thread;fn main() {let data = Mutex::new(0);let handles: Vec<_> = (0..5).map(|_| {let data = data.clone();thread::spawn(move || {let mut num = data.lock().unwrap();*num += 1;})}).collect();for h in handles {h.join().unwrap();}println!("Result: {}", *data.lock().unwrap());
}

4. RwLock<T>

  • 特點:讀寫鎖,允許多線程同時讀,寫時獨占。

  • 用途:讀多寫少的場景下性能優于 Mutex

use std::sync::RwLock;
use std::thread;fn main() {let data = RwLock::new(5);let r1 = {let data = data.clone();thread::spawn(move || {let r = data.read().unwrap();println!("Read 1: {}", *r);})};let r2 = {let data = data.clone();thread::spawn(move || {let r = data.read().unwrap();println!("Read 2: {}", *r);})};let w = {let data = data.clone();thread::spawn(move || {let mut w = data.write().unwrap();*w += 1;println!("Write: {}", *w);})};r1.join().unwrap();r2.join().unwrap();w.join().unwrap();
}

總結

類型單線程/多線程內部可變性適用場景
Cell<T>單線程是(Copy)小型簡單數據類型內部修改
RefCell<T>單線程復雜類型內部可變性,運行時檢查
Mutex<T>多線程多線程共享資源獨占訪問
RwLock<T>多線程多線程讀多寫少場景

如果需要更復雜用法示例或結合 async 異步的例子,也可以告訴我!

區別

下面是 CellRefCellMutexRwLock 的區別總結表,方便你快速對比:

類型線程安全內部可變性支持借用檢查時機適用場景額外限制
Cell<T>單線程,不安全支持(僅限 Copy 類型)編譯時(靜態檢查)單線程下對簡單 Copy 類型數據的內部修改只能存儲實現 Copy 的類型
RefCell<T>單線程,不安全支持運行時(動態檢查,違規時 panic)單線程下復雜類型的內部可變性運行時借用沖突會導致程序 panic
Mutex<T>線程安全支持運行時(通過鎖機制)多線程環境中獨占訪問共享數據獲取鎖失敗會阻塞或返回錯誤
RwLock<T>線程安全支持運行時(通過鎖機制)多線程環境中讀多寫少的共享數據寫鎖獨占,讀鎖可多線程同時訪問

簡單歸納

  • 單線程環境用 CellRefCell,根據是否限制 Copy 類型和是否能接受運行時借用檢查選擇。

  • 多線程環境用 MutexRwLock,前者適合讀寫都頻繁,后者讀多寫少時性能更優。

  • 它們都是用來實現內部可變性(即即使外部不可變,也允許修改內部數據),但適用范圍和性能開銷不同。


如果你想了解具體的性能影響或異步環境中的用法,我也可以幫你詳細說明。

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

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

相關文章

scGPT-spatial 復現

文章目錄 ? 總體流程總覽&#xff08;從 H5AD 到模型訓練&#xff09;&#x1f527; 步驟 1&#xff1a;讀取 H5AD 文件并做基礎預處理&#x1f9f1; 步驟 2&#xff1a;構造訓練樣本輸入&#xff08;token、value&#xff09;&#x1f4e6; 步驟 3&#xff1a;使用 DataColla…

運放電壓跟隨器為什么要加電阻

運放電壓跟隨器為什么要加電阻 我們常見運放的電壓跟隨器如下&#xff1a; 有時候會看見電路中加兩個電阻&#xff1a; 作用就是保護運放&#xff0c;起限流電阻的作用。 當輸入電壓高的時候&#xff0c;運放內部存在鉗位二極管&#xff0c;此電阻就能限流。 并不是所有運放…

MinerU 2.0部署

簡介 MinerU 2.0使用sglang加速&#xff0c;與之前差別較大&#xff0c;建議按照官方的Docker鏡像的方式啟動。 Docker鏡像 Dockerfile 這是官方的Dockerfile # Use the official sglang image FROM lmsysorg/sglang:v0.4.7-cu124# install mineru latest RUN python3 -m …

黑馬python(十七)

目錄&#xff1a; 1.數據可視化-地圖-基礎案例 2.全國疫情地圖 3.河南省疫情地圖繪制 4.基礎柱狀圖構建 5.基礎時間線柱狀圖繪制 6.動態GDP柱狀圖繪制 1.數據可視化-地圖-基礎案例 圖示有點對的不準&#xff0c;可以通過后面的參數 2.全國疫情地圖 3.河南省疫情地圖繪制…

Segment Anything in High Quality之SAM-HQ論文閱讀

摘要 最近的 Segment Anything Model(SAM)在擴展分割模型規模方面取得了重大突破,具備強大的零樣本能力和靈活的提示機制。盡管 SAM 在訓練時使用了 11 億個掩碼,其掩碼預測質量在許多情況下仍不理想,尤其是對于結構復雜的目標。我們提出了 HQ-SAM,使 SAM 能夠精確地分割…

深入理解_FreeRTOS的內部實現(2)

1.事件組 事件組結構體&#xff1a; 事件組 “不關中斷” 的核心邏輯 事件組操作時&#xff0c;優先選擇 “關調度器” 而非 “關中斷” &#xff0c;原因和實現如下&#xff1a; 關調度器&#xff08;而非關中斷&#xff09; FreeRTOS 提供 taskENTER_CRITICAL()&#xff08;…

【圖論題典】Swift 解 LeetCode 最小高度樹:中心剝離法詳解

文章目錄 摘要描述題解答案題解代碼分析思路來源&#xff1a;樹的“中心剝離法”構造鄰接表和度數組循環剝葉子終止條件 示例測試及結果時間復雜度空間復雜度總結 摘要 樹是一種重要的數據結構&#xff0c;在許多應用里&#xff0c;我們希望選一個根&#xff0c;讓這棵樹的高度…

Docker的介紹與安裝

? Docker 對初學者的簡單解釋和應用場景 1.什么是 Docker&#xff1f; 簡單來說&#xff0c;Docker 就像一個“裝箱子”的工具&#xff0c;這個箱子叫做“容器”。 你寫的程序和它運行需要的環境&#xff08;比如操作系統、軟件、工具&#xff09;都裝進一個箱子里。這個箱…

引導相機:工業自動化的智能之眼,賦能制造業高效升級

在工業自動化浪潮中&#xff0c;精準的視覺引導技術正成為生產效率躍升的關鍵。作為遷移科技——一家成立于2017年、專注于3D工業相機和3D視覺系統的領先供應商&#xff0c;我們深知"引導相機"的核心價值&#xff1a;它不僅是一個硬件設備&#xff0c;更是連接物理世…

智能相機如何重塑工業自動化?遷移科技3D視覺系統的場景革命

從硬件參數到產業價值&#xff0c;解碼高精度視覺系統的落地邏輯 一、工業視覺的“智慧之眼” 遷移科技深耕3D工業相機領域&#xff0c;以“穩定、易用、高回報”為核心理念&#xff0c;打造覆蓋硬件、算法、軟件的全棧式視覺系統。成立6年累計融資數億元的背后&#xff0c;是…

【數據挖掘】聚類算法學習—K-Means

K-Means K-Means是一種經典的無監督學習算法&#xff0c;用于將數據集劃分為K個簇&#xff08;clusters&#xff09;&#xff0c;使得同一簇內的數據點相似度高&#xff0c;不同簇間的相似度低。它在數據挖掘、模式識別和機器學習中廣泛應用&#xff0c;如客戶細分、圖像壓縮和…

linux環境內存滿php-fpm

檢查 PHP-FPM 配置 pm.max_children&#xff1a;該參數控制 PHP-FPM 進程池中最大允許的子進程數。過高的子進程數會導致內存占用過大。你可以根據服務器的內存大小來調整 pm.start_servers&#xff1a;控制 PHP-FPM 啟動時創建的進程數。根據實際情況調整此值。 pm.min_spare_…

基于CNN卷積神經網絡圖像識別小程序9部合集

基于CNN卷積神經網絡圖像識別小程序合集-視頻介紹下自取 ? 內容包括&#xff1a; 基于python深度學習的水果或其他物體識別小程序 003基于python深度學習的水果或其他物體識別小程序_嗶哩嗶哩_bilibili 代碼使用的是python環境pytorch深度學習框架&#xff0c;代碼的環境安…

WebRTC(九):JitterBuffer

JitterBuffer Jitter “Jitter”指的是連續到達的媒體包之間時間間隔的變化。在網絡傳輸中&#xff0c;由于&#xff1a; 網絡擁塞路由路徑變化隊列排隊不同鏈路帶寬差異 導致包之間的接收時間不一致&#xff0c;這就是網絡“抖動”。 作用 **JitterBuffer&#xff08;抖…

【推薦100個unity插件】在 Unity 中繪制 3D 常春藤,模擬生長——hedera插件的使用

注意&#xff1a;考慮到后續接觸的插件會越來越多&#xff0c;我將插件相關的內容單獨分開&#xff0c;并全部整合放在【推薦100個unity插件】專欄里&#xff0c;感興趣的小伙伴可以前往逐一查看學習。 效果演示 文章目錄 效果演示前言一、常春藤生成器工具下載二、工具使用1、…

【三維重建】【3DGS系列】【深度學習】3DGS的理論基礎知識之高斯橢球的幾何變換

【三維重建】【3DGS系列】【深度學習】3DGS的理論基礎知識之高斯橢球的幾何變換 文章目錄 【三維重建】【3DGS系列】【深度學習】3DGS的理論基礎知識之高斯橢球的幾何變換前言模型變換(Model Transformation)觀測變換(Viewing Transformation)視圖變換(View Transformation)投影…

EXISTS 和 NOT EXISTS 、IN (和 NOT IN)

在 SQL 中&#xff0c;EXISTS、NOT EXISTS 和 IN 都是用于子查詢的條件運算符&#xff0c;用于根據子查詢的結果過濾主查詢的行。它們之間的區別主要體現在工作方式、效率、對 NULL 值的處理以及適用場景上。 1. EXISTS 和 NOT EXISTS 作用&#xff1a; EXISTS: 檢查子查詢是…

GitHub 趨勢日報 (2025年06月25日)

&#x1f4ca; 由 TrendForge 系統生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日獲星趨勢圖 今日獲星趨勢圖 880 awesome 788 build-your-own-x 691 free-for-dev 427 best-of-ml-python 404 …

互聯網大廠Java求職面試:Java虛擬線程實戰

互聯網大廠Java求職面試&#xff1a;Java虛擬線程實戰 文章內容 開篇&#xff1a;技術總監與程序員鄭薪苦的三輪對話 在一場緊張而嚴肅的Java工程師面試中&#xff0c;技術總監張工正對候選人鄭薪苦進行深入提問。鄭薪苦雖然性格幽默&#xff0c;但對技術有著扎實的理解。今天…

網絡安全的兩大威脅:XSS與CSRF攻擊實例解析

在網絡攻擊中,XSS跨站腳本攻擊(Cross Site Scripting)與CSRF跨站請求偽造攻擊(Cross-Site Request Forgery)是兩種常見的攻擊方式,它們之間存在顯著的區別。以下是對這兩種攻擊方式的詳細比較: 一、攻擊原理 XSS跨站腳本攻擊 攻擊者通過在Web頁面中注入惡意腳本來實現攻…