这段内容摘自 上下文,可能会有点奇怪,但我有以下数据结构:
use std::marker::PhantomData;
pub struct Map<T, M=()> {
data: Vec<T>,
_marker: PhantomData<fn(M) -> M>,
}
Map
是一种关联映射,其中键被“标记”,以防止在另一个不相关的映射上使用同样的键。用户可以通过传递他们创建的某些唯一类型作为M
来选择加入此功能,例如:
struct PlayerMapMarker;
let mut player_map: Map<String, PlayerMapMarker> = Map::new();
这一切都很好,但是对于一些迭代器(例如只提供值的迭代器),我想为此地图编写的迭代器不包含标记在其类型中。以下转换是否安全以丢弃标记?
fn discard_marker<T, M>(map: &Map<T, M>) -> &Map<T, ()> {
unsafe { std::mem::transmute(map) }
}
所以我可以编写和使用:
fn values(&self) -> Values<T> {
Values { inner: discard_marker(self).iter() }
}
struct Values<'a, T> {
inner: Iter<'a, T, ()>,
}
fn(M) -> M
具有静态生命周期并且没有实现Drop
,将PhantomData<fn(M) -> M>
转换为PhantomData<()>
不应该有任何可观察到的效果,除了类型检查。 - Sven Marnachstruct PlayerMapMarker(String)
的值不能被添加到Map<ItemMapMarker>
中。 - E net4