这个mem::transmute::<&str,&'static str>(k)安全吗?



我正在研究这段代码,这是一个非常简单的库,只有一个文件,大部分是测试,所以它很短。我正在努力理解一个结构:

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。正因为如此,当我试图在这个映射中获取一些东西时,有问题的str必须有'static的生存期。这就是transmute的原因,对吧?如果是这样,为什么不使用String,这样我们就可以去掉寿命,从而去掉transmute?我不喜欢unsafe,读到关于transmute的文章,它看起来很不安全。

此外,我根本不明白为什么需要Cow

我认为CowStr是一个具有'static生存期的Cow,否则很难或不可能在映射中存储str。

是和否,您可以将&'static str存储在哈希图中而没有问题,问题是您不能同时存储&'static strString

我说得对吗?如果是这样,为什么不简单地使用字符串,这样我们就可以摆脱生命,从而转化?

我认为这是一种优化:使用String,每次您想在映射中插入挑战时都必须创建一个分配,但如果绝大多数挑战名称是DigestBasic,那么这是浪费时间(和内存,但大部分时间(,但同时您必须为自定义身份验证方案支持String

现在,也许从总体来看,这不是一个真正重要的优化,我不能告诉你,最好不要这样做。

我不喜欢不安全,阅读关于transmit的文章看起来很不安全。

这是一件有争议的事情,但在这种情况下;"安全";,从这个意义上说,引用对整个HashMap::get调用都有效,并且我们知道该调用并不能保持引用的有效性(它依赖于一个有点风险的实现细节,但这种情况发生变化的可能性基本为零,因为这没有多大意义(。

延长寿命本身并不是UB(mem::transmute文档确实提供了一个这样做的示例(,但需要小心,因为您必须避免它导致UB(最有可能是悬空引用(。

最新更新