2015-07-03 59 views
5

在相同類型的兩個可變位置交換值,而不進行初始化或複製任何一個。`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); 

(從offical Rust doc

如何可以在兩個值,而不拷貝被交換?價值42y變爲x是怎麼回事?這應該是不可能的。

+1

我敢打賭,你從來沒有聽說過的[三重XOR技巧]的(https://開頭恩.wikipedia.org/wiki/XOR_swap_algorithm),這是編碼訪談中的一個流行瑣事。不知道標準庫是否以這種方式實現它雖然.. – vincentleest

+0

我記得在大會的日子裏,做幾個XOR語句可以交換數據,而不需要第三個內存空間來複制。但我不確定這是什麼「交換」使用。也許你可以查看大會? https://en.wikipedia.org/wiki/XOR_swap_algorithm – Sunsetquest

+0

是啊已經聽說過它:) – Kapichu

回答

6

功能並不實際進行復印內部:這裏是它的源從文檔中提取:

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

嗯......這不完全矛盾的描述:「沒有[[]]複製」?或者他們是否意味着沒有價值會被重複? – Kapichu

+7

「生鏽級別複製」(重複值,需要釋放兩次)和實施級別複製之間存在差異。在鐵鏽語義上,這裏沒有任何副本,這兩個值只是移動。 – bluss

+1

@Kapichu這裏的「無副本」大多意味着你所做的鋸齒類型不需要是「克隆」或「複製」,這並不意味着不使用臨時存儲器。 – Levans