2015-07-03 42 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