2015-07-03 16 views
5

Zamień wartości na dwie zmienne lokalizacje tego samego typu, bez deinicjalizacji lub kopiowania jednego z nich.Jak działa `std :: mem :: swap`?

use std::mem; 

let x = &mut 5; 
let y = &mut 42; 

mem::swap(x, y); 

assert_eq!(42, *x); 
assert_eq!(5, *y); 

(Od offical Rust doc)

Jak dwie wartości mają zostać zamienione bez kopiowania? Jak zmieniła się wartość 42 z y na x? To nie powinno być możliwe.

+1

Założę się, że nigdy nie słyszał o potrójnym [xor podstęp] (https: // pl .wikipedia.org/wiki/XOR_swap_algorithm), który jest popularną ciekawostką w wywiadach kodujących. Nie jestem pewien, czy standardowa biblioteka implementuje je w ten czy inny sposób. – vincentleest

+0

Pamiętam z powrotem w dniach montażu, że wykonanie kilku instrukcji XOR może zamienić dane bez trzeciej pamięci do skopiowania. Nie jestem pewien, czy to właśnie wykorzystuje "zamiana". może możesz obejrzeć montaż? https://en.wikipedia.org/wiki/XOR_swap_algorithm – Sunsetquest

+0

Tak, już o tym słyszałem :) – Kapichu

Odpowiedz

6

Funkcja robi rzeczywiście zrobić kopię wewnętrznie: tutaj jest jego źródło pochodzących z dokumentacji:

pub fn swap<T>(x: &mut T, y: &mut T) { 
    unsafe { 
     // Give ourselves some scratch space to work with 
     let mut t: T = uninitialized(); 

     // Perform the swap, `&mut` pointers never alias 
     ptr::copy_nonoverlapping(&*x, &mut t, 1); 
     ptr::copy_nonoverlapping(&*y, x, 1); 
     ptr::copy_nonoverlapping(&t, y, 1); 

     // y and t now point to the same thing, 
     // but we need to completely forget `t` 
     // because it's no longer relevant. 
     forget(t); 
    } 
} 
+0

Um ... czy nie jest to całkowicie sprzeczne z opisem: "bez [...] kopiowania"? Czy może to oznaczać, że żadna wartość nie zostanie zduplikowana? – Kapichu

+7

Istnieje różnica między "kopiowaniem na poziomie rdzy" (powielone wartości powinny być zwolnione dwukrotnie) i kopiowaniem na poziomie implementacji. W semantyce rdzy nie ma tu kopii, obie wartości po prostu się poruszają. – bluss

+1

@Kapichu "brak kopii" oznacza przede wszystkim, że typ, w którym piła jest włączona, nie musi być "Klon" lub "Kopiuj", nie oznacza to, że nie jest używane tymczasowe miejsce na dane. – Levans