015 Rust死灵书之Transmutes转换

本系列录制的视频主要放在B站上Rust死灵书学习视频

Rust 死灵书相关的源码资料在github.com/anonymousGiga/Rustonomi...

介绍

mem::transmute<T, U> 接受一个 T 类型的值,然后将它重新解析为类型 U。要求T和U的大小一样。
这种操作是非安全的行为,可能产生未定义的行为。

示例

1、字节到类型转换

u32::from_ne_bytes  从内存转换到native字节序列类型
u32::from_be_bytes 从内存转换到大端序列类型
u32::from_le_bytes 从内存转换到小端序列类型

2、transmute

pub const unsafe extern "rust-intrinsic" fn transmute<T, U>(e: T) -> U
将一种类型的值重新解释为另一种类型。它将源值中的位复制到目标值中,然后忘记原始值。

例子:

//std::mem::transmute
//将连续的字节转换成另外一个类型,会产生为定义的行为

fn main() {
    //let raw_bytes = [0x78, 0x56, 0x34, 0x12];
    let mut raw_bytes = [0x78, 0x56, 0x34, 0x12];
    let num = unsafe {
        std::mem::transmute::<[u8; 4], u32>(raw_bytes)
    };
    let ret = u32::from_ne_bytes(raw_bytes);

    //assert_eq!(num, 0x12345678);
    assert_eq!(num, ret);
    println!("num = {}", num);
}

3、transmute_copy

pub unsafe fn transmute_copy<T, U>(src: &T) -> U
将src解释为&U类型,然后读取src的值。读取时是创建副本,而不是直接移动。

例子:

use std::mem;

#[repr(packed)]
struct Foo {
    bar: u8,
}

fn main() {
    let foo_array = [10u8];

    unsafe {
        let mut foo_struct: Foo = mem::transmute_copy(&foo_array);
        assert_eq!(foo_struct.bar, 10);

        foo_struct.bar = 20;
        assert_eq!(foo_struct.bar, 20);
    }

    assert_eq!(foo_array, [10]);
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
令狐一冲
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!