我正在查看这段代码,它是一个非常简单的库,只有一个文件和大部分测试,所以很短。我想要理解其中的结构体:
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)
}
我对这个不安全的操作感到烦恼。我认为`CowStr`是一个具有静态生命周期的`Cow`,否则将难以或不可能将`str`存储在map中。正因如此,当我尝试获取map中的某些内容时,所需的`str`必须具有`'static`生命周期。这就是使用`transmute`的原因,对吗?如果是这样,为什么不简单地使用`String`,这样我们就可以摆脱生命周期和`transmute`了呢?我不喜欢`unsafe`,而且阅读关于`transmute`的说明后,它看起来非常不安全。
另外,我不明白为什么需要使用`Cow`。
String
会触发堆分配。 - MasklinnCowStr::Owned
暗示了一个包含堆分配缓冲区的String
。 - MasklinnHashMap::insert
会进行分配,但如果它使用String
作为键,则需要为拥有的字符串进行额外的分配,这是可以避免的,并且(在代码作者的显然看法中)是不必要的。 - user4815162342