调用表达式

语法

CallExpression :

   表达式 ( CallParams? )

CallParams :

   表达式 ( , 表达式 )* ,?

调用表达式用于调用函数。调用表达式的语法是一个表达式,称为函数操作数,后跟一对括号,括号内是用逗号分隔的表达式列表,称为参数操作数。如果函数最终返回,则表达式完成。对于非函数类型,表达式 f(...) 使用 std::ops::Fnstd::ops::FnMutstd::ops::FnOnce 特征上的方法,它们的区别在于它们是按引用、可变引用还是获取所有权。如果需要,将进行自动借用。函数操作数也将根据需要自动解引用

调用表达式的一些示例

#![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 和其他社区文章中使用。但是,这些术语缺乏描述性,并且可能会混淆手头的问题。我们在这里提到它们是为了便于搜索。

经常会出现几种情况,导致方法或关联函数调用的接收者或引用不明确。这些情况可能包括

  • 多个作用域内特征为相同类型定义了具有相同名称的方法
  • 自动 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;

    // we can do this because we only have one item called `print` for `Foo`s
    f.print();
    // more explicit, and, in the case of `Foo`, not necessary
    Foo::print(&f);
    // if you're not into the whole brevity thing
    <Foo as Pretty>::print(&f);

    // b.print(); // Error: multiple 'print' found
    // Bar::print(&b); // Still an error: multiple `print` found

    // necessary because of in-scope items defining `print`
    <Bar as Pretty>::print(&b);
}

有关更多详细信息和动机,请参阅 RFC 132