% Элементы языка (lang items)
Замечание: многие элементы языка предоставляются контейнерами в стандартной поставке Rust, а у самих элементов языка нестабильный интерфейс. Рекомендуется использовать официально распространяемые контейнеры, вместо того, чтобы определять свои собственные элементы языка.
У компилятора rustc
есть некоторые подключаемые операции, т.е. функционал, не
встроенный жёстко в язык, а реализованный в библиотеках и специально помеченный
как элемент языка. Метка — это атрибут #[lang="..."]
. Есть различные значения
...
, т.е. разные «элементы языка».
Например, для указателей Box
нужны два элемента языка — для выделения памяти и
для освобождения. Вот программа, не использующая стандартную библиотеку, и
реализующая Box
через malloc
и free
:
#![feature(lang_items, box_syntax, start, no_std, libc)] #![no_std] extern crate libc; extern { fn abort() -> !; } #[lang = "owned_box"] pub struct Box<T>(*mut T); #[lang="exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { let p = libc::malloc(size as libc::size_t) as *mut u8; // malloc завершился ошибкой if p as usize == 0 { abort(); } p } #[lang="exchange_free"] unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) { libc::free(ptr as *mut libc::c_void) } #[start] fn main(argc: isize, argv: *const *const u8) -> isize { let x = box 1; 0 } #[lang = "stack_exhausted"] extern fn stack_exhausted() {} #[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
Заметьте, что exchange_malloc
должен возвращать допустимый указатель, поэтому
он производит проверку внутри и делает abort
, если она не прошла.
Ниже перечислены другие возможности, предоставляемые элементами языка:
- перегружаемые операторы через типажи: типажи, соответствующие
==
,<
, разыменованию (*
),+
и другим операторам, помечены как элементы языка; конкретно эти типажи помечены какeq
,ord
,deref
иadd
; - раскрутка стека и общая ошибка; это элементы
eh_personality
,fail
иfail_bounds_check
; - типажи в модуле
std::marker
, используемые чтобы помечать различные типы; элементыsend
,sync
иcopy
; - типы-метки и индикаторы вариантности из
std::marker
; это элементыcovariant_type
,contravariant_lifetime
и другие.
Элементы языка загружаются компилятором лениво, т.е. если программа не
использует Box
, вам не нужно определять элементы exchange_malloc
и
exchange_free
. rustc
выдаст ошибку, если элемент языка необходим, но не
найден ни в текущем контейнере, ни в его зависимостях.