2015-07-03 35 views
5

Değerler, aynı türden iki tane değiştirilebilen konumdan birinde, yeniden başlatılmadan veya kopyalanmadan değiştirilir. (offical Rust doc itibaren)std :: mem :: swap nasıl çalışır?

use std::mem; 

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

mem::swap(x, y); 

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

iki değer kopyalama olmadan takas edilebilir Nasıl

? 42 değeri, y'dan x'a nasıl geçti? Bu mümkün olmamalıydı.

+1

Sana [üçlü xor hile] duymadım bahis (https: // tr .wikipedia.org/wiki/XOR_swap_algorithm), kodlama görüşmelerinde popüler bir trivia. Standart kütüphanenin bu şekilde uygulayıp uygulamadığından emin değil misiniz? – vincentleest

+0

Montaj günlerinde, birkaç XOR ifadesinin veri kopyalamak için üçüncü bir bellek alanı olmadan verileri değiştirebileceğini hatırlıyorum. Ancak "swap" ın kullandığı şeyin bu olduğundan emin değilim. belki meclisi görebilirsin? https://en.wikipedia.org/wiki/XOR_swap_algorithm – Sunsetquest

+0

Evet, zaten duydum :) – Kapichu

cevap

6

işlevi aslında içten bir kopyasını yapar: Burada belgelere çıkarılan onun kaynağıdır:

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 ... bu, tamamen "[...] kopyalanmadan" açıklamasıyla çelişmiyor mu? Ya da hiçbir değerin kopyalanmayacağı anlamına mı geliyor? – Kapichu

+7

“Pas düzeyi kopyalama” (yinelenen değerler, iki kez serbest bırakılması gerekir) ve uygulama düzeyinde kopyalama arasında bir fark var. Pas semantiğinde, burada hiç kopya yoktur, iki değer hareket eder. – bluss

+1

@Kapichu "no copy" burada çoğunlukla testere işini yaptığınız türün "Clone" veya "Copy" olması gerekmediği anlamına gelir, bu geçici bellek deposunun kullanılmadığı anlamına gelmez. – Levans