Замечание: многие элементы языка предоставляются контейнерами в стандартной поставке 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
выдаст ошибку, если элемент языка необходим, но не
найден ни в текущем контейнере, ни в его зависимостях.