调用表达式
语法
CallExpression :
表达式(调用参数?)
调用表达式用于调用函数。其语法是一个表达式,称为 函数操作数,后跟用括号括起来的、逗号分隔的表达式列表,称为 参数操作数。
如果函数最终返回,则该表达式完成。
对于非函数类型,表达式 f(...) 会根据函数操作数使用以下 trait 之一的方法
Fn或AsyncFn— 共享引用。FnMut或AsyncFnMut— 可变引用。FnOnce或AsyncFnOnce— 值。
如果需要,将进行自动借用。函数操作数也将根据需要被自动解引用。
调用表达式的一些示例
#![allow(unused)] fn main() { fn add(x: i32, y: i32) -> i32 { 0 } let three: i32 = add(1i32, 2i32); let name: &'static str = (|| "Rust")(); }
消除函数调用的歧义
所有函数调用都是更显式的完全限定语法的语法糖。
函数调用可能需要完全限定,这取决于调用相对于作用域内项的歧义性。
注意
过去,术语“Unambiguous Function Call Syntax”(无歧义函数调用语法)、“Universal Function Call Syntax”(通用函数调用语法)或“UFCS”在文档、issue、RFC 和其他社区著作中被使用。然而,这些术语缺乏描述性力量,并可能混淆当前的问题。我们在此提及它们是为了方便搜索。
以下几种情况经常发生,导致方法或关联函数调用的接收者或被引用者产生歧义。这些情况可能包括:
- 多个作用域内的 trait 为相同的类型定义了同名方法
- 自动
deref(解引用)是不可取的;例如,区分智能指针本身的方法与指针所指向对象的方法 - 不接受参数的方法,例如
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; // 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。