A method call consists of an expression followed by a single dot, an identifier, and a parenthesized expression-list. Method calls are resolved to methods on specific traits, either statically dispatching to a method if the exact self
-type of the left-hand-side is known, or dynamically dispatching if the left-hand-side expression is an indirect trait object. Method call expressions will automatically take a shared or mutable borrow of the receiver if needed.
# #![allow(unused_variables)] #fn main() { let pi: Result<f32, _> = "3.14".parse(); let log_pi = pi.unwrap_or(1.0).log(2.72); # assert!(1.14 < log_pi && log_pi < 1.15) #}
When resolving method calls on an expression of type A
, Rust will use the following order, only looking at methods that are visible and traits that are in scope:
A
, &A
, &mut A
.A
.&A
.&mut A
.<A as std::ops::Deref>::Target
, and insert a dereference operator.A
is now an array type, then repeat steps 1-4 with the corresponding slice type.Note: that in steps 1-4 the receiver is used, not the type of Self
nor the type of A
. For example
// `Self` is `&A`, receiver is `&A`. impl<'a> Trait for &'a A { fn method(self) {} } // If `A` is `&B`, then `Self` is `B` and the receiver is `A`. impl B { fn method(&self) {} }
Another note: this process does not use the mutability or lifetime of the receiver, or whether unsafe
methods can currently be called to resolve methods. These constraints instead lead to compiler errors.
If a step is reached where there is more than one possible method (where generic methods or traits are considered the same), then it is a compiler error. These cases require a more specific syntax. for method and function invocation.
© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.
https://doc.rust-lang.org/reference/expressions/method-call-expr.html