Ассоциированные функции в отличие от методов относятся не к конкретному объекту структуры, а ко всей структуре в целом. В некоторых языках программирования есть похожая концепция - статические методы. В Rust ассоциированные функции часто применяются для создания объекта структуры.
Ассоциированные функции, как и методы, определяются с помощью блока impl:
impl структура {
fn название_функции(){
// выполняемые действия
}
}
После оператора impl указывается название структуры, к которой относится функция. Но в отличие от метода ассоциированная функция не принимает
ссылку на текущий объект self, так как относится ко всей структуре, а не к отдельному объекту.
Для вызова ассоциированной функции применяется оператор :::
название_структуры::функция();
После названия структуры идет оператор ::, а затем имя функции, после которой в скобках указываются значения для ее параметров.
Распространенным примером ассоциированной функции является встроенная функция String::from(), которая принимает строковый слайс &str и возвращает
объект структуры String. Например:
fn main(){
let hello: String = String::from("hello");
println!("{}", hello); // hello
let message = String::from("Rust on Metanit.com");
println!("{}", message); // Rust on Metanit.com
}
Теперь определим свою простейшую ассоциированную функцию, которая будет создавать объект структуры:
fn main(){
let tom = Person::create("Tom", 36);
println!("Name: {} Age: {}", tom.name, tom.age);
let bob = Person::create("Bob", 41);
println!("Name: {} Age: {}", bob.name, bob.age);
}
struct Person { name: String, age: u8 }
impl Person{
fn create(user_name: &str, user_age: u8) -> Person{
Person {
name: String::from(user_name),
age: user_age
}
}
}
Здесь для структуры Person определена ассоциированная функция create(), которая принимает два параметра - строку и число и по ним создает
объект Person, который возвращается функцией.
В функции main с помощью данной функции создаем объект Person:
let tom = Person::create("Tom", 36);
Вместо конкретного типа данных внутри ассоциированной функции можно использовать специальный заменитель для текущего типа - Self:
fn main(){
let tom = Person::create("Tom", 36);
println!("Name: {} Age: {}", tom.name, tom.age);
let bob = Person::create("Bob", 41);
println!("Name: {} Age: {}", bob.name, bob.age);
}
struct Person { name: String, age: u8 }
impl Person{
fn create(user_name: &str, user_age: u8) -> Self{
Self {
name: String::from(user_name),
age: user_age
}
}
}