【发布时间】:2021-04-24 04:07:53
【问题描述】:
我有一些struct,类似这样的:
struct MyStruct<T> {
field1: T,
field2: T,
field3: T,
}
我对@987654323@ 的了解和确信:
- 所有字段的类型相同;
- 所有字段均为
Sized; - 每个
struct(本例中为3)的准确字段数;
在我的项目中,像切片一样访问structs 可能很有用。所以我做了什么:
impl<T> AsRef<[T]> for MyStruct<T> {
fn as_ref(&self) -> &[T] {
let ptr = self as *const Self;
let ptr2 = ptr as *const T;
unsafe { std::slice::from_raw_parts(ptr2, 3) }
}
}
现在我可以像这样访问MyStruct 的字段:
let s = MyStruct { field1: 1.0, field2: 2.0, field3: 3.0 };
s.as_ref()[1]
我已经在dev 和release 模式下测试了一些示例,但没有发现任何错误。我仍然不确定这种指针魔术。
Rust 不能保证内存布局会保持字段的顺序。另一方面,据我所知,只有当struct 的字段大小不同且需要对齐时才会发生这种情况。
所以我真的很好奇:
- 是否存在任何违反防锈安全保证的情况?
- 此变体与下一个变体之间是否存在安全或性能差异?
- 我应该使用
union来代替这个技巧吗?
impl<T> AsRef<[T]> for MyStruct<T> {
fn as_ref(&self) -> &[T] {
let tmp: &[T; 3] = unsafe { std::mem::transmute(self) };
tmp.as_ref()
}
}
【问题讨论】:
标签: rust unsafe memory-layout