Search CTRL + K

rust 标准库 std::mem 的一个细节

在 rust 标准库 std::mem 中有三个变量“替换”的函数:

  1. std::mem::take:将变量 dest 替换为其类型的默认值,并返回原来的 dest

    pub fn take<T>(dest: &mut T) -> T
    where
        T: Default,
    
  2. std::mem::replace:将 src 移动到 dest,并返回原来的 dest

    pub fn replace<T>(dest: &mut T, src: T) -> T
    
  3. std::mem::swap:交换两个可变变量的值

    pub fn swap<T>(x: &mut T, y: &mut T)
    

需要注意的是,所有的值交换都是 浅拷贝,也就是说如果两个变量内含堆(heap)上的内容,堆内容不会交换,而是交换堆地址的引用。

例子一:take

rust palyground

use std::mem;

fn main() {
    let mut hello = vec![1, 2, 3];

    println!("hello ({:?}) address: {:p}, internal buffer address: {:p}", hello, &hello, &*hello);
    let old_hello = mem::take(&mut hello);
    println!("hello ({:?}) address: {:p}, internal buffer address: {:p}; old_hello ({:?}) address: {:p}, internal buffer address: {:p}", hello, &hello, &*hello, old_hello, &old_hello, &*old_hello);
}

结果如下:

hello ([1, 2, 3]) address: 0x7ffd7257abe8, internal buffer address: 0x5639f36959d0
hello ([]) address: 0x7ffd7257abe8, internal buffer address: 0x4; old_hello ([1, 2, 3]) address: 0x7ffd7257ac78, internal buffer address: 0x5639f36959d0

例子二:replace

rust playground

use std::mem;

fn main() {
    let mut hello = vec![1, 2, 3];

    println!("hello ({:?}) address: {:p}, internal buffer address: {:p}", hello, &hello, &*hello);
    let old_hello = mem::replace(&mut hello, vec![4, 5, 6]);
    println!("hello ({:?}) address: {:p}, internal buffer address: {:p}; old_hello ({:?}) address: {:p}, internal buffer address: {:p}", hello, &hello, &*hello, old_hello, &old_hello, &*old_hello);
}

结果如下:

hello ([1, 2, 3]) address: 0x7ffc309a86f0, internal buffer address: 0x560fea5ee9d0
hello ([4, 5, 6]) address: 0x7ffc309a86f0, internal buffer address: 0x560fea5ee9f0; old_hello ([1, 2, 3]) address: 0x7ffc309a8780, internal buffer address: 0x560fea5ee9d0

例子三:swap

rust playground

use std::mem;

fn main() {
    let mut hello1 = vec![1, 2, 3];

    let mut hello2 = vec![4, 5, 6];

    println!("hello1 ({:?}) address: {:p}, internal buffer address: {:p}; hello2 ({:?}) address: {:p}, internal buffer address: {:p}", hello1, &hello1, &*hello1, hello2, &hello2, &*hello2);
    mem::swap(&mut hello1, &mut hello2);
    println!("hello1 ({:?}) address: {:p}, internal buffer address: {:p}; hello2 ({:?}) address: {:p}, internal buffer address: {:p}", hello1, &hello1, &*hello1, hello2, &hello2, &*hello2);
}

结果如下:

hello1 ([1, 2, 3]) address: 0x7fff773fa2b0, internal buffer address: 0x5618b26639d0; hello2 ([4, 5, 6]) address: 0x7fff773fa2c8, internal buffer address: 0x5618b26639f0
hello1 ([4, 5, 6]) address: 0x7fff773fa2b0, internal buffer address: 0x5618b26639f0; hello2 ([1, 2, 3]) address: 0x7fff773fa2c8, internal buffer address: 0x5618b26639d0