常用Trait

常用Trait

Copy

Copy特性定义在标准库std::marker::Copy中:

pub trait Copy: Clone { }

一旦一种类型实现了Copy特性,这就意味着这种类型可以通过的简单的位(bits)拷贝实现拷贝。从前面知识我们知道“绑定”存在move语义(所有权转移,但是,一旦这种类型实现了Copy特性,会先拷贝内容到新内存区域,然后把新内存区域和这个标识符做绑定。

哪些情况下我们自定义的类型(如某个Struct等)可以实现Copy特性? 只要这种类型的属性类型都实现了Copy特性,那么这个类型就可以实现Copy特性。例如:

struct Foo {  //可实现Copy特性
    a: i32,
    b: bool,
}

struct Bar {  //不可实现Copy特性
    l: Vec<i32>,
}

因为Foo的属性ab的类型i32bool均实现了Copy特性,所以Foo也是可以实现Copy特性的。但对于Bar来说,它的属性lVec类型,这种类型并没有实现Copy特性,所以Bar也是无法实现Copy特性的。

有两种方式可以实现Copy特性:

  • 通过deriveRust编译器自动实现
 #[derive(Copy, Clone)]
 struct Foo {
     a: i32,
     b: bool,
 }

编译器会自动检查Foo的所有属性是否实现了Copy特性,一旦检查通过,便会为Foo自动实现Copy特性。

  • 手动实现CloneCopy trait
#[derive(Debug)]
 struct Foo {
     a: i32,
     b: bool,
 }
 impl Copy for Foo {}
 impl Clone for Foo {
     fn clone(&self) -> Foo {
         Foo{a: self.a, b: self.b}
     }
 }
 fn main() {
     let x = Foo{ a: 100, b: true};
     let mut y = x;
     y.b = false;

     println!("{:?}", x);  //打印:Foo { a: 100, b: true }
     println!("{:?}", y);  //打印:Foo { a: 100, b: false }
 }

从结果我们发现let mut y = x后,x并没有因为所有权move而出现不可访问错误。因为Foo继承了Copy特性和Clone特性,所以例子中我们实现了这两个特性。

上一页