Введение
В этом лабораторном задании при работе с обобщениями в Rust параметры типа должны быть ограничены трейтами, чтобы указать функциональность, которую должен реализовать тип.
Примечание: Если лабораторная работа не уточняет имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать
main.rs, скомпилировать и запустить его с помощьюrustc main.rs &&./main.
Границы
При работе с обобщениями параметры типа часто должны использовать трейты в качестве границ, чтобы определить, какую функциональность реализует тип. Например, в следующем примере используется трейт Display для печати, поэтому требуется, чтобы T был ограничен Display; то есть T должен реализовать Display.
// Определите функцию `printer`, которая принимает обобщенный тип `T`, который
// должен реализовать трейт `Display`.
fn printer<T: Display>(t: T) {
println!("{}", t);
}
Ограничение ограничивает обобщенный тип типами, которые соответствуют ограничениям. То есть:
struct S<T: Display>(T);
// Ошибка! `Vec<T>` не реализует `Display`. Эта
// специализация не будет работать.
let s = S(vec![1]);
Другим эффектом ограничения является то, что обобщенные экземпляры могут обращаться к [методам] трейтов, указанных в ограничениях. Например:
// Трейт, который реализует маркер печати: `{:?}`.
use std::fmt::Debug;
trait HasArea {
fn area(&self) -> f64;
}
impl HasArea for Rectangle {
fn area(&self) -> f64 { self.length * self.height }
}
#[derive(Debug)]
struct Rectangle { length: f64, height: f64 }
#[allow(dead_code)]
struct Triangle { length: f64, height: f64 }
// Обобщенный `T` должен реализовать `Debug`. Независимо от
// типа, это будет работать правильно.
fn print_debug<T: Debug>(t: &T) {
println!("{:?}", t);
}
// `T` должен реализовать `HasArea`. Любой тип, который соответствует
// границе, может обратиться к функции `area` `HasArea`.
fn area<T: HasArea>(t: &T) -> f64 { t.area() }
fn main() {
let rectangle = Rectangle { length: 3.0, height: 4.0 };
let _triangle = Triangle { length: 3.0, height: 4.0 };
print_debug(&rectangle);
println!("Area: {}", area(&rectangle));
//print_debug(&_triangle);
//println!("Area: {}", area(&_triangle));
// ^ TODO: Попробуйте раскомментировать эти строки.
// | Ошибка: Не реализует ни `Debug`, ни `HasArea`.
}
В качестве дополнительной примечания, в некоторых случаях для более выразительного представления можно также использовать where-клоузы для применения ограничений.
Резюме
Поздравляем! Вы завершили лабораторную работу по Границам. Вы можете практиковаться в других лабораторных работах в LabEx, чтобы улучшить свои навыки.