首页 > 解决方案 > 有没有办法为与底层存储不匹配的类型创建可变引用?

问题描述

考虑一个实现为[u8; 2]. 是否可以构造&mut u16对整个结构的可变引用?有安全的方法吗?

作为表达这一点的另一种方式,有没有一种方法可以实现:

fn ref_all(&mut [u8; 2]) -> &mut u16

有没有办法为自定义类型做这个?

标签: rustreferencemutableunsafe

解决方案


没有完全安全的方法可以做到这一点,但是为切片定义了align_to_mut(及其不可变的对应物align_to),它适用于所有类型,并且是比大锤子更安全的替代方案mem::transmute

fn ref_all(x: &mut [u8; 2]) -> &mut u16 {
    let (prefix, chunks, suffix) = unsafe {x.align_to_mut::<u16>()};

    // you don't need these asserts but know that chunks might not always have an element
    assert!(prefix.is_empty());
    assert!(suffix.is_empty());
    assert_eq!(chunks.len(), 1);

    &mut chunks[0]
}

对于u16s,这应该没问题,尽管由于数字的字节顺序,它可能会导致依赖于架构的行为。对于其他类型,这样做会非常冒险。


推荐阅读