Copy
与Clone trait
的区别与关联
-
从继承层次来讲,
Clone
是Copy
的Supertrait
。因此,所有Copy
类型也一定是Clone
类型。 -
从被复制的内容来讲,
Copy
仅只对【栈】内存做【按位复制】,而不对任何【堆】内存负责。而,Clone
需要对复本的整体有效性负责,所以【栈】与【堆】都是Clone
的复制目标。由此可知,String
与Vec<T>
皆为!Copy
的原因是:它们保存的数据主体都在【堆】上;而【栈】上仅有它们的一对智能指针。因此,Copy
对String
与Vec<T>
完全没有意义。 -
从复制行为的定义来讲,
Copy
【按位复制】的技术细节是完全被密封在rustc
内。开发者基本没有办法介入与定制,仅只能通过给类实现Copy marker trait
来暗示rustc
对此类实例做【按位复制】。另一方面,Clone
的所有操作细节都必须由开发者在Clone::clone(&self)
成员方法的实现内明确地指定。这算是将业务定制权全面下放给开发者了。所以,rust
也不从语言层面保证Clone
行为的执行效率。相反,这应该是开发者自己担负的事。 -
从复制行为的触发时机,
Copy
行为在【(1)赋值(2)参数传入(3)结果传出】时被【隐式】地触发。而,Clone
行为必须经由Clone::clone(&self)
成员方法调用来【显示】地触发。后者明显更直观一些,也少了许多的“黑魔法”。 -
从
trait
实现的技术限制来讲,Copy trait
的实现约束比较苛刻,包含两条:- 类的所有成员都是
Copy
的。“成员(member
)”的含义取决于类型,例如:结构体的字段、枚举的变量、数组的元素、元组的项,等等。 - 类没有实现
Drop trait
。即,!Drop
类型。因为Drop
类实例的内容主体一般不在【栈】上。要么像String
,其关键数据存在【堆】上;要么,类似于【数据库连接】,其关键数据在操作系统上。而仅只复制一个智能指针真没有意义。
另一方面,Clone trait 对实现类几乎没有任何的限制。一切皆由着开发者来;一切也皆由开发者好自为之。
- 类的所有成员都是
评论区
写评论赞,到时给你笔记汇总一下,公众号推一把