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

Небезопасный трейт

Небезопасный трейт объявляется с помощью ключевого слова unsafe перед словом trait. Такой трейт накладывает особые обязательства на того, кто его реализует: реализация должна соблюдать определённые инварианты, которые компилятор не в состоянии проверить. Если тип реализует небезопасный трейт, программист берёт на себя ответственность за то, что все требования трейта выполнены. Параметров у объявления трейта нет - он лишь помечает набор методов как потенциально опасный для реализации.

Основное отличие небезопасного трейта от небезопасной функции заключается в том, что ключевое слово unsafe относится к реализации трейта, а не к его вызову. Это означает, что вызывать методы такого трейта можно в обычном безопасном коде, но реализовывать его разрешено только внутри блока unsafe impl.

Синтаксис

unsafe trait TraitName { // methods } unsafe impl TraitName for TypeName { // implementations }

Пример

Давайте объявим небезопасный трейт UnsafeMarker и реализуем его для структуры MyType:

unsafe trait UnsafeMarker { fn describe(&self) -> String; } struct MyType { value: i32, } unsafe impl UnsafeMarker for MyType { fn describe(&self) -> String { format!("MyType with value {}", self.value) } } fn main() { let obj = MyType { value: 42 }; let res = obj.describe(); println!("{}", res); }

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

"MyType with value 42"

Пример

Рассмотрим более практичный пример: небезопасный трейт RawBytes, который обязует тип иметь корректное представление в памяти. Реализация помечена как unsafe impl:

unsafe trait RawBytes { fn as_bytes(&self) -> &[u8]; } struct Packet { data: [u8; 4], } unsafe impl RawBytes for Packet { fn as_bytes(&self) -> &[u8] { &self.data } } fn main() { let packet = Packet { data: [1, 2, 3, 4] }; let res = packet.as_bytes(); println!("{:?}", res); }

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

[1, 2, 3, 4]

Пример

Небезопасный трейт может также требовать реализации небезопасных методов. Давайте объявим трейт с небезопасным методом и реализуем его:

unsafe trait UnsafeOps { unsafe fn raw_double(&self, ptr: *const i32) -> i32; } struct Doubler; unsafe impl UnsafeOps for Doubler { unsafe fn raw_double(&self, ptr: *const i32) -> i32 { (*ptr) * 2 } } fn main() { let doubler = Doubler; let value: i32 = 21; let res = unsafe { doubler.raw_double(&value) }; println!("{}", res); }

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

42

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

  • ключевое слово unsafe,
    которое открывает блок небезопасного кода
  • unsafe fn,
    которая объявляет небезопасную функцию
  • unsafe impl,
    которая реализует небезопасный трейт
  • transmute,
    которая небезопасно преобразует тип одного значения в другой
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить