瀏覽 std::cell::Cell 的檔案,我看不到如何檢索對內部資料的非可變參考。只有get_mut方法:https ://doc.rust-lang.org/std/cell/struct.Cell.html#method.get_mut
我不想使用此功能,因為我想擁有&self而不是&self mut.
我找到了采用原始指標的替代解決方案:
use std::cell::Cell;
struct DbObject {
key: Cell<String>,
data: String
}
impl DbObject {
pub fn new(data: String) -> Self {
Self {
key: Cell::new("some_uuid".into()),
data,
}
}
pub fn assert_key(&self) -> &str {
// setup key in the future if is empty...
let key = self.key.as_ptr();
unsafe {
let inner = key.as_ref().unwrap();
return inner;
}
}
}
fn main() {
let obj = DbObject::new("some data...".into());
let key = obj.assert_key();
println!("Key: {}", key);
}
有沒有辦法在不使用不安全的情況下做到這一點?如果沒有,也許 RefCell 在這里會更實用?
謝謝你的幫助!
uj5u.com熱心網友回復:
首先,如果你有 a &mut T,你可以很容易地從中得到 a &T。所以你可以使用get_mut來獲取&T.
但是&mut T要從 a中獲取 a ,Cell<T>您需要該單元格是可變的,因為get_mut它需要一個&mut self引數。這是通過設計獲得對單元格內部物件的參考的唯一方法。
通過要求使用&mut self方法從單元格中獲取參考,您可以在編譯時使用借用檢查器檢查獨占訪問。請記住,單元格啟用內部可變性,并且有一個方法set(&self, val: T),即可以修改非mut系結值的方法!如果有get(&self) -> &T方法,借用檢查器無法確保您在設定物件時不持有對內部物件的參考,這是不安全的。
TL;DR:按照設計,您無法從&T非mut Cell<T>. 使用get_mut(需要一個mut單元格),或set/ replace(在非mut單元格上作業)。如果這是不可接受的,那么請考慮使用RefCell,它可以讓您&T擺脫非 mut 實體,但需要一些運行時成本。
uj5u.com熱心網友回復:
除了@mcarton 的回答,為了保持內部可變性健全,即不允許可變參考與其他參考共存,我們有三種不同的方式:
- 使用
unsafe未定義行為的可能性。這就是這樣UnsafeCell做的。 - 進行一些運行時檢查,涉及運行時開銷。這就是方法
RefCell和RwLock使用Mutex。 - 限制抽象可以完成的操作。這就是
Cell,Atomic*and (unstable)OnceCell(因此Lazy使用它)所做的(請注意,執行緒安全型別也有運行時開銷,因為它們需要提供某種鎖定)。每個都提供一組不同的允許操作:Cell并且Atomic*不要讓您獲得對包含值的參考,而只能將其全部替換(基本上,get()andset,盡管在這些之上提供了方便的方法,例如swap())。投影(細胞切片到細胞切片)也可用于Cell(場投影是可能的,但不作為標準的一部分提供)。OnceCell允許您只分配一次,然后才獲取共享參考,確保您在分配時沒有參考,而當您有共享參考時,您不能再分配。
因此,當您需要能夠參考內容時,您不能選擇Cell,因為它不是為此而設計的 - 顯而易見的選擇RefCell確實是 。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/415993.html
標籤:
上一篇:如何用Jqueryanimate()中的變換替換邊距影片以修復滯后的多滑塊
下一篇:將值從函式回傳到全域變數
