Существует ли стандартный способ циклически вращающихся изменяемых переменных в Rust?
Нет.
Я бы просто дважды поменял переменные, без необходимости unsafe
:
use std::mem;
pub fn rotate<T>(x: &mut T, y: &mut T, z: &mut T) {
mem::swap(x, y);
mem::swap(y, z);
}
fn main() {
let mut a = 1;
let mut b = 2;
let mut c = 3;
println!("{}, {}, {}", a, b, c);
// 1, 2, 3
rotate(&mut a, &mut b, &mut c);
println!("{}, {}, {}", a, b, c);
// 2, 3, 1
}
Это дает 7 movl
инструкций (Rust 1.35.0, Release, x86_64, Linux)
playground::rotate:
movl (%rdi), %eax
movl (%rsi), %ecx
movl %ecx, (%rdi)
movl %eax, (%rsi)
movl (%rdx), %ecx
movl %ecx, (%rsi)
movl %eax, (%rdx)
retq
В отличие от оригинального 6 movl
Инструкция:
playground::rotate_original:
movl (%rdx), %eax
movl (%rsi), %ecx
movl %ecx, (%rdx)
movl (%rdi), %ecx
movl %ecx, (%rsi)
movl %eax, (%rdi)
retq
Я в порядке, отказываясь от этой единственной инструкции для чисто безопасного кода, о котором также легче рассуждать.
В «реальном» коде яиспользовать тот факт, что все переменные имеют одинаковый тип и существуют slice::rotate_left
и slice::rotate_right
:
fn main() {
let mut vals = [1, 2, 3];
let [a, b, c] = &vals;
println!("{}, {}, {}", a, b, c);
// 1, 2, 3
vals.rotate_left(1);
let [a, b, c] = &vals;
println!("{}, {}, {}", a, b, c);
// 2, 3, 1
}