赞
踩
Rust 程序中的变量可以分成两类:实现 Copy trait 的和没实现 Copy trait 的。这有啥区别?当然很重要!
如果你的数据类型包含数据量较大,而且你用内部的指针指向这些大的数据块,那么你完整复制这样的变量需要很大的代价,这种情况下,建议不要实现 Copy trait。因为在代码中,赋值语句、函数调用等场合,一不小心就会触发 copy 操作,影响程序效率。
相反,你可以利用 clone 方法显式复制变量。
Clone 与 Copy 都是复制当前变量,产生一个副本,二者的差别在于 Rust 语法或语义。Clone方法表明可以用显式的方法产生一个变量的副本,这一般意味着当前变量内部可能有指针,部分数据可能在堆上分配。同时也常常意味着这类变量的使用存在所有权转移问题。
clone 和 copy 这两种方法的实现代码,没有什么区别,区别就在于 Rust 的语法和语义方面。
一般来讲是这样的,但不排除特殊需要。
为便于理解这个问题,我们先看一个例子:
let a = Arc::new(123);
let b = a.clone();
从 Rust 语义上看,a、b 是两个完全独立的变量。从编程的角度看,后续代码认为 a、b 不存在所有权转移问题,他们在存储空间上不存在任何个联系。但是,实际上二者是共享数据的,因为 Arc 是一个共享计数指针。
这个例子告诉我们,如果有必要,可以用一些技巧欺骗 Rust 编译器的。所以我设想,Arc 这样的数据类型,与其不厌其烦地调用 clone 复制数据,倒不如直接实现 Copy trait,这样的话,上面的代码可以写成下面的形式:
let a = Arc::new(123);
let b = a;
注意,如果 Arc 实现了 Copy trait,那么编译器认为 let b = a
只是把数据复制了一个完整、独立的副本,变量 a 中数据的所有权并没有转移。当然,Rust 并没有为 Arc 实现 trait,但我坚信,未来我们一定能看到有 Rust 代码库实现类似的机制。
在 Rust 中,Copy
和 Clone
是两个重要的 trait,它们允许开发者复制数据的实例。尽管这两个 trait 都与复制有关,但它们之间有一些重要的区别。
Copy
trait 是一个标记 trait,没有定义任何方法。如果一个类型实现了 Copy
,那么它表明该类型的值可以通过简单的位拷贝来复制,而不会导致任何运行时开销或可能的副作用。换句话说,Copy
类型的值在赋值或作为函数参数传递时,不需要显式地调用 .clone()
或其他复制方法,而是可以隐式地、低成本地进行位拷贝。
要实现 Copy
trait,一个类型必须满足以下条件:
Copy
的。Box
, Vec
, 或 String
这样的类型)。由于 Copy
允许隐式复制,所以应该谨慎地为其实现,以避免意外地多次复制可能导致的问题。
与 Copy
不同,Clone
trait 定义了一个名为 clone
的方法,它返回一个与原始对象具有相同值的新对象。如果一个类型实现了 Clone
,那么它可以使用 .clone()
方法来显式地创建一个副本。
与 Copy
相比,Clone
更加通用和灵活。例如,它可以用于复制那些包含堆上数据的类型,这些数据不能简单地通过位拷贝来复制。
Copy
是隐式的,而 Clone
需要显式调用 .clone()
方法。Copy
是低成本的位拷贝,而 Clone
可能涉及更复杂的复制操作,特别是当涉及到堆上数据时。Copy
,因为它有一些严格的限制。但大多数类型都可以实现 Clone
。Copy
主要用于优化和简化代码,而 Clone
提供了一种更通用的复制机制。总之,当你知道一个类型可以通过简单的位拷贝来安全地复制时,你可以为其实现 Copy
。如果你需要一种更通用的复制机制,或者当类型包含堆上数据时,你应该使用 Clone
。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。