[英]Is this mem::transmute::<&str, &'static str>(k) safe?
我正在查看這個代碼,它是一個非常簡單的庫,只有一個文件並且主要是測試,所以它很短。 我試圖理解一個結構:
pub struct ChallengeFields(HashMap<UniCase<CowStr>, (String, Quote)>);
struct CowStr(Cow<'static, str>);
有一條線
pub fn get(&self, k: &str) -> Option<&String> {
self.0
.get(&UniCase(CowStr(Cow::Borrowed(unsafe {
mem::transmute::<&str, &'static str>(k)
}))))
.map(|&(ref s, _)| s)
}
我對這種unsafe
的操作感到惱火。 我認為CowStr
是具有'static
生命周期”的Cow
,否則很難或不可能將str
存儲在 map 內。 正因為如此,當我試圖在這個 map 中獲取一些東西時,有問題的str
必須具有'static
生命周期”。 這就是transmute
的原因吧? 如果是這樣,為什么干脆不使用String
,這樣我們就可以擺脫生命周期,從而transmute
? 我不喜歡unsafe
,並且閱讀有關transmute
的內容看起來非常不安全。
另外,我根本不明白為什么需要Cow
。
我認為
CowStr
是具有'static
生命周期”的Cow
,否則很難或不可能將 strs 存儲在 map 內。
好吧,是也不是,您可以毫無問題地將&'static str
存儲在 hashmap 中,問題是您不能同時存儲&'static str
和String
。
我說得對嗎? 如果是這樣,為什么干脆不使用字符串,這樣我們就可以擺脫生命周期,從而轉化?
我認為這是一種優化:使用String
時,每次您想在 map 中插入挑戰時都必須創建分配,但如果絕大多數挑戰名稱是Digest
和Basic
,那么這是浪費時間(並且memory 但主要是時間),但同時您必須支持自定義身份驗證方案的String
。
現在,也許從總體上看,這並不是一個真正重要的優化,最好不要這樣做,我不能告訴你。
我不喜歡不安全的,並且閱讀有關 transmute 的內容看起來非常不安全。
這是一件值得商榷的事情,但在這種情況下它是“安全的”,因為引用對整個HashMap::get
調用有效,我們知道該調用不會使引用保持活動狀態(它是依賴在一個有點冒險的實現細節上,但改變的可能性基本上為零,因為它沒有多大意義)。
延長生命周期本身並不是 UB( mem::transmute
文檔確實提供了一個這樣做的示例),但需要小心,因為您必須避免它導致 UB(最有可能是懸空引用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.