РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
464 of 1245 menu

Трейт 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,
    который освобождает ресурсы при уничтожении значения
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить