mem::transmute() 函数
这个函数用于将一个值从当前类型转换成另一种类型. 类似于C语言中的强制类型转换. 要注意的是, 源类型与目标类型应该大小相同.
use std::mem; fn main() { let pack: [u8; 4] = [0x01, 0x02, 0x03, 0x04]; let pack_u32 = unsafe { mem::transmute::<[u8; 4], u32>(pack) }; assert_eq!(pack_u32, 0x04030201); }
相同的功能, 用C语言实现:
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
int main() {
uint8_t pack[4] = {0x01, 0x02, 0x03, 0x04};
uint32_t pack_u32 = *(uint32_t*)pack;
assert(pack_u32 == 0x04030201);
return 0;
}
将枚举转换为 u8
用这个函数也可以将枚举结构中的签标 tag 值转为 u8 或者别的整数类型:
use std::mem; #[derive(Debug, Clone, Copy)] pub enum Shape { Rectangle, Circle, Ellipse, } impl Shape { pub fn tag(&self) -> u8 { unsafe { mem::transmute(*self) } } } fn main() { let c = Shape::Circle; println!("c.tag() is {}", c.tag()); }
手动构造切片引用
切片引用本身就是一个胖指针:
- data ptr: 指向切片元素的起始内存
- len: 切片中元素的个数
use std::mem; fn main() { let nums = [0_i32, 1, 2, 3]; let slice: &[i32] = unsafe { let nums_addr: usize = nums.as_ptr() as usize; let len = nums.len(); mem::transmute([nums_addr, len]) }; assert_eq!(slice.len(), 4); assert_eq!(slice[2], 2); assert_eq!(slice[3], 3); }