Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Типы функциональных элементов

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

Этот тип явно идентифицирует функцию - ее имя, аргументы типа и ранние аргументы времени жизни (но не поздние аргументы времени жизни, которые назначаются только при вызове функции) - поэтому значение не нужно содержать фактический указатель на функцию, и не требуется косвенное обращение при вызове функции.

Нет синтаксиса, который бы непосредственно ссылался на тип функционального элемента, но компилятор будет отображать тип как что-то вроде fn(u32) -> i32 {fn_name} в сообщениях об ошибках.

Поскольку тип функционального элемента явно идентифицирует функцию, типы элементов разных функций - разных элементов или одного и того же элемента с разными обобщениями - различны, и их смешение вызовет ошибку типа:

#![allow(unused)]
fn main() {
fn foo<T>() { }
let x = &mut foo::<i32>;
*x = foo::<u32>; //~ ОШИБКА: несоответствие типов
}

Однако существует приведение из функциональных элементов в указатели на функции с той же сигнатурой, которое срабатывает не только когда функциональный элемент используется там, где ожидается указатель на функцию, но и когда разные типы функциональных элементов с той же сигнатурой встречаются в разных ветвях одного if или match:

#![allow(unused)]
fn main() {
let want_i32 = false;
fn foo<T>() { }

// `foo_ptr_1` здесь имеет тип указателя на функцию `fn()`
let foo_ptr_1: fn() = foo::<i32>;

// ... и `foo_ptr_2` тоже - это проходит проверку типов.
let foo_ptr_2 = if want_i32 {
    foo::<i32>
} else {
    foo::<u32>
};
}

Все функциональные элементы реализуют Copy, Clone, Send и Sync.

Fn, FnMut и FnOnce реализуются, если только функция не имеет любого из следующего: