PhantomData 用于区分类型

  1. 没有具体类型,没有强类型校验,导致类型错误
fn ping_user(user_id: u64) {
   //...
}
let group_id = new_group_id(); 
ping_user(group_id); // This compiles!
  1. New Type,定义新的类型,类型校验, 需要给每一种类型都实现大量方法
struct GroupId(u64);
struct UserId(u64);
...

fn ping_user(id: UserId) {
    //...
}

ping_user(GroupId(12345)); // This triggers an error!
  1. 一个更好的解决方案
struct Id<T> {
    inner: u64,
    _marker: std::marker::PhantomData<T>,
}
impl<T> Id<T> {
    pub fn new(inner: u64) -> Self { 
       Self {
           inner, 
           _marker: std::marker::PhantomData
        }
    }
}
struct UserIdMarker;
struct GroupIdMarker;

pub type UserId = Id<UserIdMarker>;
pub type GroupId = Id<GroupIdMarker>;