pub unsafe fn write<T>(dst: *mut T, src: T)
Expand description
用给定值覆盖存储位置,而无需读取或丢弃旧值。
write
不会丢弃 dst
的内容。
这是安全的,但可能会泄漏分配或资源,因此应注意不要覆盖应丢弃的对象。
此外,它不会丢弃 src
。在语义上,src
被移到 dst
指向的位置。
这适用于初始化未初始化的内存,或覆盖以前是 read
的内存。
Safety
如果违反以下任一条件,则行为是未定义的:
-
dst
必须是 有效的 才能写入。 -
dst
必须正确对齐。如果不是这种情况,请使用write_unaligned
。
请注意,即使 T
的大小为 0
,指针也必须非空且正确对齐。
Examples
基本用法:
let mut x = 0;
let y = &mut x as *mut i32;
let z = 12;
unsafe {
std::ptr::write(y, z);
assert_eq!(std::ptr::read(y), 12);
}
Run手动实现 mem::swap
:
use std::ptr;
fn swap<T>(a: &mut T, b: &mut T) {
unsafe {
// 在 `tmp` 中的 `a` 处创建值的按位副本。
let tmp = ptr::read(a);
// 此时退出 (通过显式返回或调用 panics 的函数) 将导致 `tmp` 中的值被丢弃,而 `a` 仍引用相同的值。
// 如果 `T` 不是 `Copy`,则可能触发未定义的行为。
// 在 `a` 中的 `b` 处创建值的按位副本。
// 这是安全的,因为可变引用不能使用别名。
ptr::copy_nonoverlapping(b, a, 1);
// 如上所述,退出此处可能会触发未定义的行为,因为 `a` 和 `b` 引用了相同的值。
// 将 `tmp` 移至 `b`。
ptr::write(b, tmp);
// `tmp` 已移动 (`write` 对其第二个参数的所有权),因此这里没有隐含地丢弃任何东西。
}
}
let mut foo = "foo".to_owned();
let mut bar = "bar".to_owned();
swap(&mut foo, &mut bar);
assert_eq!(foo, "bar");
assert_eq!(bar, "foo");
Run