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

Трейт Send

Трейт Send - это маркерный трейт, который сообщает компилятору, что значение типа можно безопасно перемещать в другой поток. Тип реализует Send автоматически, если все его поля также являются Send. Трейт не содержит методов и используется как ограничение в дженериках и многопоточных примитивах, например в thread::spawn.

Параметров у трейта нет, так как это маркерный трейт без методов. Основное применение - указывать компилятору и функциям, что значение можно передавать между потоками.

Синтаксис

pub unsafe auto trait Send { } // as a bound fn foo<T: Send>(value: T) { }

Пример

Давайте передадим значение типа i32 в другой поток. Такой тип реализует Send автоматически, поэтому код компилируется:

use std::thread; fn main() { let value = 12345; let handle = thread::spawn(move || { println!("{}", value); }); handle.join().unwrap(); }

Результат выполнения кода:

12345

Пример

Давайте попробуем передать в поток значение типа Rc<i32>. Тип Rc не реализует Send, поэтому такой код не скомпилируется:

use std::rc::Rc; use std::thread; fn main() { let value = Rc::new(12345); let handle = thread::spawn(move || { println!("{}", value); }); handle.join().unwrap(); }

Компилятор выдаст ошибку:

error[E0277]: `Rc<i32>` cannot be sent between threads safely

Пример

Давайте напишем дженерик-функцию с ограничением T: Send и вызовем её для типа i32 и для типа String. Оба типа реализуют Send:

fn check_send<T: Send>(value: T) -> T { value } fn main() { let a = check_send(12345); let b = check_send(String::from("abcde")); println!("{}", a); println!("{}", b); }

Результат выполнения кода:

12345 "abcde"

Пример

Давайте реализуем Send вручную через unsafe impl для собственной обёртки. Такой код снимает автоматическую проверку компилятора и требует уверенности в безопасности:

struct MyBox<T>(T); unsafe impl<T: Send> Send for MyBox<T> { } use std::thread; fn main() { let value = MyBox(12345); let handle = thread::spawn(move || { println!("{}", value.0); }); handle.join().unwrap(); }

Результат выполнения кода:

12345

Смотрите также

  • трейт Sync,
    который разрешает доступ к значению из нескольких потоков
  • трейт Sized,
    который указывает на известный размер типа на этапе компиляции
  • трейт Trait Bound,
    который задаёт ограничения на дженерик-параметры
  • трейт impl Trait,
    который позволяет указывать трейт в возвращаемом типе
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить