在C++中,我可以使用模板参数作为标记,使数据类型相同但不相关:
template<typename T>
struct UniqueId
{
int Value;
};
struct CustomerTag{};
struct BookTag{};
using BookId = UniqueId<BookTag>;
using CustomerId = UniqueId<CustomerTag>;
我可以在Rust中做同样的事情,但是遇到了问题,因为我的类型开始表现得好像它 * 拥有 * 一个T,而它并没有。所以现在,为了使我的类型为Clone
,Send
,等等。* 我的标记也必须为 * Clone
,Send
,等等。这有点奇怪,因为我的类型并不真正拥有T
。文档似乎建议PhantomData<*const T>
可以解决这个问题,但似乎没有,因为我只得到*const BookTag cannot be sent between threads safely
错误而不是BookTag cannot be sent between threads safely
错误。
struct UniqueId<T>
{
Value : i32,
Phantom : PhantomData<*const T>
}
1条答案
按热度按时间ruarlubt1#
使用
PhantomData<fn(T) -> T>
,它在T上是不变的,并且总是Copy
、Clone
、Send
和Sync
。唯一的缺点是,您必须为UniqueId<T>
结构体编写手动的Copy
和Clone
实现,因为派生宏当前总是生成T: Copy
/T: Clone
绑定。即使在不必要时也是如此(参见this issue)。Playground example