Что такое перемещение в Rust
Всегда побитовое копирование, даже для типов, которые не реализуют Copy:
// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0
#[derive(Debug, Default)]
pub struct DynamicBuffer {
data: Vec<u8>,
position: usize,
};
pub fn move_and_inspect(x: DynamicBuffer) { println!("{x:?}"); }
pub fn main() {
let a = DynamicBuffer::default();
let mut b = a;
b.data.push(b'R');
b.data.push(b'U');
b.data.push(b'S');
b.data.push(b'T');
move_and_inspect(b);
}
Сгенерированный LLVM IR для вызова move_and_expect():
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %_12, ptr align 8 %b, i64 32, i1 false)
invoke void @move_and_inspect(ptr align 8 %_12)
memcpyиз переменной%bв%_12- Вызов
move_and_inspectс%_12(копией)
Обратите внимание, что DynamicBuffer не реализует Copy.
Следствие: адрес памяти значения не стабилен.
Чтобы показать перемещение как побитовое копирование, откройте код в песочнице и посмотрите на вывод, либо откройте Compiler Explorer.
Необязательно для тех, кто предпочитает вывод ассемблера:
Compiler Explorer полезен для обсуждения сгенерированного ассемблера. Установите курсор на вывод ассемблера в функции main, строки 128–136 (они должны подсвечиваться розовым).
Соответствующий сгенерированный вывод move_and_inspect:
mov rax, qword ptr [rsp + 16]
mov qword ptr [rsp + 48], rax
mov rax, qword ptr [rsp + 24]
mov qword ptr [rsp + 56], rax
movups xmm0, xmmword ptr [rsp]
movaps xmmword ptr [rsp + 32], xmm0
lea rdi, [rsp + 32]
call qword ptr [rip + move_and_inspect@GOTPCREL]