Динамическая диспетчеризация в Rust: изучение концепций и примеров кода

Фраза «armanriazi•rust•concept•dynamic•dispatch» представляет собой комбинацию ключевых слов, связанных с языком программирования Rust и динамической диспетчеризацией. Динамическая диспетчеризация – это концепция программирования, при которой соответствующая реализация функции или метода определяется во время выполнения на основе фактического типа объекта, над которым выполняется операция.

Вот несколько методов в Rust, демонстрирующих динамическую отправку:

  1. Объекты свойств:

    trait Shape {
    fn area(&self) -> f64;
    }
    struct Circle {
    radius: f64,
    }
    impl Shape for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
    }
    struct Rectangle {
    width: f64,
    height: f64,
    }
    impl Shape for Rectangle {
    fn area(&self) -> f64 {
        self.width * self.height
    }
    }
    fn print_area(shape: &dyn Shape) {
    println!("Area: {}", shape.area());
    }
    fn main() {
    let circle = Circle { radius: 3.0 };
    let rectangle = Rectangle { width: 2.0, height: 4.0 };
    print_area(&circle);
    print_area(&rectangle);
    }
  2. Динамическая отправка на основе перечисления:

    enum Shape {
    Circle(Circle),
    Rectangle(Rectangle),
    }
    impl Shape {
    fn area(&self) -> f64 {
        match self {
            Shape::Circle(circle) => std::f64::consts::PI * circle.radius * circle.radius,
            Shape::Rectangle(rectangle) => rectangle.width * rectangle.height,
        }
    }
    }
    struct Circle {
    radius: f64,
    }
    struct Rectangle {
    width: f64,
    height: f64,
    }
    fn main() {
    let shapes: Vec<Shape> = vec![
        Shape::Circle(Circle { radius: 3.0 }),
        Shape::Rectangle(Rectangle { width: 2.0, height: 4.0 }),
    ];
    for shape in shapes {
        println!("Area: {}", shape.area());
    }
    }

Эти примеры демонстрируют два распространенных подхода к обеспечению динамической диспетчеризации в Rust. В первом примере используются объекты типажа, где признак определяется и реализуется различными типами, а затем объекты этих типов передаются как ссылки в функцию, которая принимает объект типажа. Во втором примере перечисление используется для представления различных фигур, а метод areaреализован непосредственно в перечислении.