Например, функция верификации возраста, которая проверяет возраст в годах
struct Years(i64);
struct Days(i64);
impl Years {
pub fn to_days(&self) -> Days {
Days(self.0 * 365)
}
}
impl Days {
pub fn to_years(&self) -> Years {
Years(self.0 / 365)
}
}
fn old_enough(age: &Years) -> bool {
age.0 >= 18
}
fn main() {
let age = Years(5);
let age_days = age.to_days();
println!("Old enough {}", old_enough(&age));
println!("Old enough {}", old_enough(&age_days.to_years()));
}
Удалите комментарий с последнего println, чтобы увидеть, что тип должен быть Years.
Чтобы получить из newtype-переменной значение базового типа, вы можете использовать кортежный синтаксис, как в примере:
struct Years(i64);
fn main() {
let years = Years(42);
let years_as_primitive: i64 = years.0;
}
struct
"Ассоциированные элементы" относятся к набору правил, касающихся элементов различных типов. Это расширение для обобщённых типажей, которое позволяет им определить новый элемент внутри себя.
Каждый такой элемент называется
trait, являющийся обобщённым для своего контейнера, есть требование к спецификации типа - пользователи trait
В примере ниже, trait Contains позволяет использовать обобщённые типы A и B. Затем этот типаж реализуется для типа Container, в котором A и B специфицированы, как i32, чтобы их можно было использовать в функции fn difference().
Потому что Contains имеет обобщение, мы должны явно указать
struct Container(i32, i32);
// Типаж, который проверяет, сохранены ли 2 элемента в контейнере.
// Также он может вернуть первое или последнее значение.
trait Contains {
fn contains(&self, _: &A, _: &B) -> bool; // Явно требует `A` и `B`.
fn first(&self) -> i32; // Не требует явного `A` или `B`.
fn last(&self) -> i32; // Не требует явного `A` или `B`.
}
impl Contains
// Истина, если сохранённые цифры равны.
fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
(&self.0 == number_1) && (&self.1 == number_2)
}
// Берём первую цифру.
fn first(&self) -> i32 { self.0 }
// Берём последнюю цифру.
fn last(&self) -> i32 { self.1 }
}
// `C` содержит `A` и `B`. В свете этого, необходимость снова явно указывать `A` и
// `B` огорчает.
fn difference(container: &C) -> i32 where
C: Contains {
container.last() - container.first()
}
fn main() {
let number_1 = 3;
let number_2 = 10;
let container = Container(number_1, number_2);
println!("Содержатся ли в контейнере {} и {}? {}",
&number_1, &number_2,
container.contains(&number_1, &number_2));
println!("Первое число: {}", container.first());
println!("Последнее число: {}", container.last());
println!("Разница: {}", difference(&container));
}