Macro std::ptr::addr_of_mut 1.51.0[−][src]
macro_rules! addr_of_mut { ($place:expr) => { ... }; }
Expand description
创建一个 mut
裸指针到一个位置,而无需创建中间引用。
仅当指针正确对齐并指向初始化数据时,才允许使用 &
/&mut
创建引用。
对于那些不满足要求的情况,应改用裸指针。
但是,&mut expr as *mut _
在将其强制转换为裸指针之前会创建一个引用,并且该引用与所有其他引用都遵循相同的规则。
该宏可以创建一个裸指针,而无需先创建一个引用。
但请注意,addr_of_mut!(expr)
中的 expr
仍受所有常规规则的约束。
特别是,addr_of_mut!(*ptr::null_mut())
是未定义行为,因为它解引用空指针。
Examples
创建指向未对齐数据的指针:
use std::ptr; #[repr(packed)] struct Packed { f1: u8, f2: u16, } let mut packed = Packed { f1: 1, f2: 2 }; // `&mut packed.f2` 会导致未对齐的引用,从而成为未定义的行为! let raw_f2 = ptr::addr_of_mut!(packed.f2); unsafe { raw_f2.write_unaligned(42); } assert_eq!({packed.f2}, 42); // `{...}` 强制复制字段,而不创建引用。Run
创建指向未初始化数据的指针:
use std::{ptr, mem::MaybeUninit}; struct Demo { field: bool, } let mut uninit = MaybeUninit::<Demo>::uninit(); // `&uninit.as_mut().field` 将创建对未初始化的 `bool` 的引用,因此是未定义的行为! let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) }; unsafe { f1_ptr.write(true); } let init = unsafe { uninit.assume_init() };Run