我正在尝试为C集合库(Judy Arrays [1])编写Rust绑定,它只为存储指针宽度值提供了空间.我的公司有相当数量的现有代码,它使用这个空间直接存储非指针值,如指针宽度整数和小结构.我希望我的Rust绑定允许使用泛型类型安全地访问此类集合,但是无法使指针存储语义正常工作.
该mem::transmute()函数似乎是实现所需行为的一种潜在工具,但尝试在参数化类型的实例上使用它会产生令人困惑的编译错误.
示例代码:
pub struct Example<T> {
v: usize,
t: PhantomData<T>,
}
impl<T> Example<T> {
pub fn new() -> Example<T> {
Example { v: 0, t: PhantomData }
}
pub fn insert(&mut self, val: T) {
unsafe {
self.v = mem::transmute(val);
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果错误:
src/lib.rs:95:22: 95:36 error: cannot transmute to or from a type that contains type parameters in its interior [E0139]
src/lib.rs:95 self.v = mem::transmute(val);
^~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
这是否意味着只包含参数"在其内部包含类型参数"的类型,因此transmute()在这里不起作用?有正确方法的任何建议吗?
(相关问题,试图获得相同的结果,但不一定通过mem::transmute().)
[1]我知道现有的rust-judy项目,但它不支持我想要的指针存储,而且我正在编写这些新的绑定,主要是作为一种学习练习.
您可以将 a转换T为,而不是直接转换为:usize&T&usize
pub fn insert(&mut self, val: T) {
unsafe {
let usize_ref: &usize = mem::transmute(&val);
self.v = *usize_ref;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果 的大小T小于 的大小usize或者对齐要求不同,则可能会从无效的内存位置读取。这可能会导致段错误。您可以添加一个断言来防止这种情况:
assert_eq!(mem::size_of::<T>(), mem::size_of::<usize>());
assert!(mem::align_of::<usize>() <= mem::align_of::<T>());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
448 次 |
| 最近记录: |