调用表达式

语法
调用语法 :
   表达式 ( 调用参数组? )

调用参数组 :
   表达式 ( , 表达式 )* ,?

调用表达式 调用函数。 调用表达式的语法是一个称为 函数操作数 表达式,后面跟着一个带括号的逗号分隔的表达式列表,称为 参数操作数 。 如果函数最终返回,则表达式完成。 对于 非函数类型 ,表达式 f(...) 使用 std::ops::Fnstd::ops::FnMutstd::ops::FnOnce trait 中的方法,这些 trait 在是否通过引用、可变引用或取得所有权方面有所不同。 如果需要,将自动借用。函数操作数也将根据需要 自动解引用

以下是一些调用表达式的例子:

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

消除函数调用的歧义

所有函数调用都是 完全限定语法 的语法糖。 根据调用的歧义性以及作用域内的条目,函数调用可能需要完全限定。

注意:在过去,术语 "无歧义函数调用语法" 、 "通用函数调用语法" 或 "UFCS" 已被用于文档、问题、 RFC 和其他社区资料。 但是,这些术语缺乏描述能力,可能会让问题变得更加混乱。 在这里提及是为了便于内容检索。

有几种常见情况可能导致方法或关联函数调用的接收者或引用产生歧义。 这些情况可能包括:

  • 多个作用域内的 trait 为相同类型定义了同名方法
  • 不希望自动解引用;例如,区分智能指针本身的方法和指针引用的方法
  • 不带参数的方法,例如 default() ,返回类型的属性,例如 size_of()

为了解决歧义,程序员可以使用更具体的路径、类型或 trait 来指定他们想要的方法或函数。

例如:

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);
}

Refer to RFC 132 for further details and motivations.