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

Выражения вызовов

Syntax
CallExpressionExpression ( CallParams? )

CallParamsExpression ( , Expression )* ,?

Выражение вызова вызывает функцию. Синтаксис выражения вызова: выражение, называемое функциональным операндом, за которым следует заключенный в круглые скобки разделенный запятыми список выражений, называемых операндами аргументов.

Если функция в конечном итоге возвращает значение, то выражение завершается.

Для не-функциональных типов выражение f(...) использует метод одного из следующих трейтов в зависимости от функционального операнда:

Автоматическое заимствование будет выполнено при необходимости. Функциональный операнд также будет автоматически разыменован по мере необходимости.

Некоторые примеры выражений вызовов:

#![allow(unused)]
fn main() {
fn add(x: i32, y: i32) -> i32 { 0 }
let three: i32 = add(1i32, 2i32);
let name: &'static str = (|| "Rust")();
}

Разрешение неоднозначности вызовов функций

Все вызовы функций являются синтаксическим сахаром для более явного полностью квалифицированного синтаксиса.

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

Note

В прошлом термины “Unambiguous Function Call Syntax”, “Universal Function Call Syntax” или “UFCS” использовались в документации, issues, RFC и других материалах сообщества. Однако этим терминам не хватает описательной силы, и они потенциально запутывают суть вопроса. Мы упоминаем их здесь для удобства поиска.

Несколько ситуаций часто возникают, которые приводят к неоднозначностям относительно получателя или референта вызовов методов или ассоциированных функций. Эти ситуации могут включать:

  • Несколько трейтов в области видимости определяют методы с одинаковыми именами для одних и тех же типов
  • Авто-deref нежелателен; например, различение методов на самом умном указателе и референте указателя
  • Методы, которые не принимают аргументов, такие как default(), и возвращают свойства типа, такие как size_of()

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

Например,

trait Pretty {
    fn print(&self);
}

trait Ugly {
    fn print(&self);
}

struct Foo;
impl Pretty for Foo {
    fn print(&self) {}
}

struct Bar;
impl Pretty for Bar {
    fn print(&self) {}
}
impl Ugly for Bar {
    fn print(&self) {}
}

fn main() {
    let f = Foo;
    let b = Bar;

    // мы можем сделать это, потому что у нас только один элемент с именем `print` для `Foo`
    f.print();
    // более явно и, в случае `Foo`, не необходимо
    Foo::print(&f);
    // если вы не любите краткость
    <Foo as Pretty>::print(&f);

    // b.print(); // Ошибка: найдено несколько 'print'
    // Bar::print(&b); // Все еще ошибка: найдено несколько `print`

    // необходимо из-за элементов в области видимости, определяющих `print`
    <Bar as Pretty>::print(&b);
}

Обратитесь к RFC 132 для получения дополнительных деталей и мотивации.