【问题标题】:How does one generically duplicate a value in Rust?如何在 Rust 中复制一个值?
【发布时间】:2018-07-18 20:08:34
【问题描述】:

原语应该像往常一样通过值传递,任何通过引用传递(“借用”)的东西都应该被克隆。比如:

let a = 7;
let b = duplicate(a);  // let b = a;

let a = struct{}{};
let b = duplicate(a);  // let b = a.clone();

这假设 Rust 中的每个值都实现了 CloneCopy 特征。这个假设是真的吗?如果没有,是否可以定义一个特征Duplicate,它类似于enum { Clone, Copy }

【问题讨论】:

  • struct{}{} 不是有效的 Rust 语法。

标签: rust


【解决方案1】:

这假设 Rust 中的每个值都实现了 CloneCopy 特征。这个假设是真的吗?

没有。

是否可以定义一个特征Duplicate

是的,但除了现有的 Clone 特征之外,它似乎没有任何价值。


您可能希望了解有关所有权的更多信息,因为您可以在不进行任何克隆的情况下编译您的代码:

fn duplicate<T>(x: T) -> T { x } // sic

fn main() {
    let a = 7;
    let b = duplicate(a);

    let a = String::from("example");
    let b = duplicate(a);
}

如果你真的想复制,只需使用Clone,就像anything that implements Copy must implement Clone

pub trait Copy: Clone { }

您通常会将其视为方法语法:

fn main() {
    let a = 7;
    let b: i32 = a.clone();

    let a = String::from("example");
    let b: String = a.clone();
}

如果你想要一个函数,使用完全限定的语法:

fn main() {
    let a = 7;
    let b: i32 = Clone::clone(&a);

    let a = String::from("example");
    let b: String = Clone::clone(&a);
}

或者

fn main() {
    let a = 7;
    let b: i32 = i32::clone(&a);

    let a = String::from("example");
    let b: String = String::clone(&a);
}

这里所有显式类型 (: foo) 都是多余的,仅用于演示目的。

【讨论】:

  • 您提议的duplicate 函数不是拥有x 的所有权吗?这正是我想要规避的。
  • @tillyboy 是的,这就是我添加// sic 的原因。您编写的代码没有任何其他需要。
【解决方案2】:

Copy 暗示 Clone。您可以将.clone() 用于您的重复功能。

【讨论】:

    【解决方案3】:
    unsafe fn duplicate <T> (item: &T) -> T {
      std::ptr::read(item)
    }
    

    编辑 - 建议用户谨慎:

    • 当类型不是自内存管理时,它可能与同一类型存在于内存中,也可能不存在,或者内存不再可访问,在这种情况下会发生 SEGFAULT。

    • 对于任何类型,无论是否非复制,它都会根据类型的布局对内存区域进行按位复制。它不会通过取消引用地址进行嵌套复制,它会复制引用/地址;即,浅拷贝(来自与语言无关的分类法)。

    对于任何 Copy 类型,这应该是 A-OK,但没用?

    我认为这是一个用例,在某些情况下,一个类型可能无法实现 Copy 和 Clone,因为另一个 trait 需要它不实现它,因此当一个人想要将它移动到另一个范围/变量/线程时可以直接读取它的内存。

    我不确定,如果您有用例,请发表评论!

    【讨论】:

    • 这会为几乎所有非Copy 类型调用UB,尤其是那些管理任何资源的类型,例如StringVec&lt;T&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2018-11-06
    相关资源
    最近更新 更多