首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何‘`std::mem::swap`’工作?

如何‘`std::mem::swap`’工作?
EN

Stack Overflow用户
提问于 2015-07-03 19:39:57
回答 2查看 3.7K关注 0票数 12

在两个相同类型的可变位置交换值,而不去初始化或复制任何一个。使用std::mem;让x= &mut 5;y= &mut 42;mem::交换(x,y);assert_eq!(42,*x);assert_eq!(5,*y);

(来自官方锈病医生)

如何在不复制的情况下交换两个值?42的值是如何从yx的?这是不可能的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-03 20:22:57

该函数实际上在内部复制:以下是从文档中提取的源代码:

代码语言:javascript
运行
复制
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);
    }
}
票数 11
EN

Stack Overflow用户

发布于 2020-05-15 16:49:16

先前的回答在语义上是正确的,但在具体细节上却过时了。

从逻辑上讲,交换两个值的方法是将值A读入临时位置,将B复制到A之上,然后将临时值写回B中。在内存中存在两次相同值的短暂时间。这就是为什么这些函数的实现需要unsafe代码,因为只有人才能保证Rust的安全要求得到维护。

截至锈菌1.43.0,被实现为

代码语言:javascript
运行
复制
pub fn swap<T>(x: &mut T, y: &mut T) {
    // SAFETY: the raw pointers have been created from safe mutable references satisfying all the
    // constraints on `ptr::swap_nonoverlapping_one`
    unsafe {
        ptr::swap_nonoverlapping_one(x, y);
    }
}

swap_nonoverlapping_one是私有的,但其实施情况是:

代码语言:javascript
运行
复制
pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
    // For types smaller than the block optimization below,
    // just swap directly to avoid pessimizing codegen.
    if mem::size_of::<T>() < 32 {
        let z = read(x);
        copy_nonoverlapping(y, x, 1);
        write(y, z);
    } else {
        swap_nonoverlapping(x, y, 1);
    }
}

您可以看到ptr::copy_nonoverlappingptr::swap_nonoverlapping的文档。后者基本上是对较大值进行复制的高度优化版本。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31213286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档