Трейт Copy
Трейт Copy помечает типы, значения которых
можно копировать простым присваиванием. Когда тип
реализует Copy, при присваивании или передаче
в функцию происходит не перемещение владения, а
побитовое копирование значения. Исходная переменная
остаётся доступной для дальнейшего использования.
Трейт не имеет методов - это маркерный трейт.
Тип может реализовать Copy только в том случае,
если все его поля также реализуют Copy.
Примитивные типы, такие как числа, bool и
char, уже реализуют этот трейт. Типы, владеющие
кучей, например String или Vec,
не могут реализовать Copy.
Синтаксис
#[derive(Copy, Clone)]
struct MyStruct
{
field: i32,
}
Трейт Copy требует, чтобы тип также реализовал
трейт Clone. Обычно оба трейта выводятся
автоматически через #[derive(Copy, Clone)].
Пример
Примитивные типы реализуют Copy. Давайте
присвоим значение переменной a переменной
b и проверим, что обе переменные доступны:
fn main()
{
let a = 5;
let b = a;
println!("a = {}, b = {}", a, b);
}
Результат выполнения кода:
a = 5, b = 5
Пример
Давайте создадим структуру, которая реализует
Copy, и проверим, что после присваивания
исходная переменная остаётся доступной:
#[derive(Copy, Clone)]
struct Point
{
x: i32,
y: i32,
}
fn main()
{
let p1 = Point { x: 1, y: 2 };
let p2 = p1;
println!("p1 = ({}, {}), p2 = ({}, {})", p1.x, p1.y, p2.x, p2.y);
}
Результат выполнения кода:
p1 = (1, 2), p2 = (1, 2)
Пример
Давайте передадим значение типа, реализующего
Copy, в функцию и проверим, что исходная
переменная остаётся доступной после вызова:
fn print_value(n: i32)
{
println!("value = {}", n);
}
fn main()
{
let a = 42;
print_value(a);
println!("a still = {}", a);
}
Результат выполнения кода:
value = 42
a still = 42
Пример
Тип String не реализует Copy. Давайте
убедимся, что при присваивании происходит перемещение
владения, а не копирование:
fn main()
{
let a = String::from("abcde");
let b = a;
println!("b = {}", b);
}
Этот код компилируется, потому что переменная a
больше не используется после перемещения. Если
добавить println!("{}", a) после присваивания,
компилятор выдаст ошибку, так как владение уже
перемещено.
Смотрите также
-
трейт
Clone,
который создаёт явную копию значения -
механизм
перемещения,
который передаёт владение значением -
концепция
владения,
которая управляет временем жизни значений -
трейт
Drop,
который освобождает ресурсы при уничтожении значения