Methods
Methods are functions defined inside a struct block that can be called on instances of that struct.
struct_def = [ directives ] [ "pub" ] "struct" IDENT "{" [ field_list ] [ method_list ] "}" ;
field_list = field_def { "," field_def } [ "," ] ;
field_def = [ "pub" ] IDENT ":" type ;
method_list = method_def { method_def } ;
method_def = [ directives ] [ "pub" ] "fn" IDENT "(" [ method_params ] ")" [ "->" type ] block ;
method_params = method_param { "," method_param } [ "," ] ;
method_param = "self" | ( IDENT ":" type ) ;
Method Definition
A method is a function defined inside a struct block that takes self as its first parameter.
The self parameter represents the receiver value and has the type of the enclosing struct.
struct Point {
x: i32,
y: i32,
fn get_x(self) -> i32 {
self.x
}
}
fn main() -> i32 {
let p = Point { x: 42, y: 10 };
p.get_x() // Returns 42
}
Method Calls
Methods are called using dot notation: receiver.method(args).
A method call receiver.method(args) is desugared to a function call with the receiver as the first argument.
Methods MAY have additional parameters after self.
struct Point {
x: i32,
y: i32,
fn add(self, dx: i32, dy: i32) -> Point {
Point { x: self.x + dx, y: self.y + dy }
}
}
fn main() -> i32 {
let p = Point { x: 10, y: 20 };
let p2 = p.add(32, 0);
p2.x // Returns 42
}
Method Chaining
When a method returns the same struct type, method calls MAY be chained.
struct Counter {
value: i32,
fn inc(self) -> Counter {
Counter { value: self.value + 1 }
}
}
fn main() -> i32 {
let c = Counter { value: 39 };
c.inc().inc().inc().value // Returns 42
}
Associated Functions
A function in a struct block that does not take self as its first parameter is an associated function.
Associated functions are called using path notation: Type::function(args).
struct Point {
x: i32,
y: i32,
fn origin() -> Point {
Point { x: 0, y: 0 }
}
}
fn main() -> i32 {
let p = Point::origin();
p.x // Returns 0
}
Multiple Methods
A struct may have multiple methods defined in its block.
Method names MUST be unique within a struct definition.
struct Point {
x: i32,
y: i32,
fn get_x(self) -> i32 { self.x }
fn get_y(self) -> i32 { self.y }
}
fn main() -> i32 {
let p = Point { x: 42, y: 10 };
p.get_x() // Returns 42
}
Error Conditions
Calling a method on a non-struct type is a compile-time error.
Calling an undefined method is a compile-time error.
Calling an associated function with method call syntax (receiver.function()) is a compile-time error.
Calling a method with associated function syntax (Type::method()) is a compile-time error.
Method Visibility
(ADR-0073.) A method definition MAY be prefixed with the pub keyword. A method marked pub is callable from any module that can name the enclosing struct or enum. A method without pub is callable only from within the same module as the type definition.
The visibility check applies to both instance method calls (receiver.method(...)) and associated function calls (Type::function(...)). Interface methods (declared in interface blocks) are not subject to this check; an interface's methods are part of the interface's public contract wherever the interface itself is in scope.
pub struct Counter {
value: i32,
pub fn new() -> Counter { Counter { value: 0 } } // public
pub fn get(self) -> i32 { self.value } // public
fn validate(self) -> bool { self.value >= 0 } // module-private
}
Self Inside Methods and Associated Functions (ADR-0076)
Inside any method or associated function defined within a struct or enum body, the type symbol Self denotes the enclosing struct or enum type. Self is in scope for the method's parameter types, return type, local-binding type annotations, struct/enum literals, enum variant paths, and pattern paths.
Self substitutes uniformly at every depth of a type expression: inside Ref(Self), MutRef(Self), Ptr(Self), MutPtr(Self), Vec(Self), Option(Self), Result(Self, E), [Self; N], (Self, T), and any user-defined parameterised type. There is no position in a type expression where Self is meaningful but does not resolve.
Associated functions — methods declared without a self parameter — also have Self in scope. Their return type and parameter types MAY mention Self, and so MAY their bodies via expressions such as Self { ... } (struct literal), Self::Variant(...) (enum variant constructor), and Self::associated_fn(...) (associated call).
struct Pair {
a: i32,
b: i32,
fn new(a: i32, b: i32) -> Self { // 6.4:29
Self { a: a, b: b } // 6.4:29
}
fn combine(self: Ref(Self), other: Ref(Self)) -> Self { // 6.4:28 (Ref(Self))
Self { a: self.a + other.a, b: self.b + other.b }
}
}
Using Self in a position where no enclosing struct, enum, derive, or interface body is in scope (for example, in a free top-level function) is a compile-time error.