【Rust】トレイト

Rustのトレイトとは共通の振る舞いを定義すること。
トレイトとはデータ型を分類する仕組み。
トレイト内に共通のメソッドを定義する。

struct Rect { width: u32, height: u32 }

trait Printable { fn print(&self); }
impl Printable for Rect {
    fn print(&self){
        println!("width:{}, height:{}", self.width, self.height)
    }
}

fn main(){
    let r = Rect { width: 200, height: 300 };
    r.print();
}
struct Rect<T> { width: T, height: T }

trait Printable { fn print(&self); }
impl<T> Printable for Rect<T> where T: std::fmt::Display {
    fn print(self: &Rect<T>){
        println!("width:{}, height:{}", self.width, self.height);
    }
}

fn main(){
    let r1: Rect<i32> = Rect { width: 200, height: 300 };
    let r2: Rect<i64> = Rect { width: 200, height: 300 };
    r1.print();
    r2.print();
}
use std::boxed::Box;

struct Dog {}
struct Cat {}
trait Animal { fn cry(&self); }
impl Animal for Dog { fn cry(&self) {println!("Bow-wow");}}
impl Animal for Cat { fn cry(&self) {println!("Miaow");}}

fn get_animal(animal_type: &str) -> Box<dyn Animal> {
    if animal_type == "dog" {
        return Box::new(Dog {});
    } else {
        return Box::new(Cat {});
    }
} 

fn main(){
    get_animal("dog").cry();
    get_animal("cat").cry();
}

C++のテンプレート

#include <iostream>
#include <cmath>

struct Point {
    double x, y;
};


template <typename T>
class DistanceCalculator {
public:
    double calculateDistance(const T& point1, const T& point2) {
        return std::sqrt(std::pow(point2.x - point1.x, 2) + std::pow(point2.y - point1.y, 2));
    }
};

auto main(void) -> int {
    Point p1 = {1.0, 2.0};
    Point p2 = {4.0, 6.0};

    DistanceCalculator<Point> calculator;
    std::cout << "Distance: " << calculator.calculateDistance(p1, p2) << std::endl;

    return 0;
}

$ g++ -o test test.cpp && ./test
Distance: 5

struct Point<T> {
    x1: T, y1: T, x2: T, y2: T,
}

trait DistanceCalculator { fn calculate(&self); }
impl<T> DistanceCalculator for Point<T> where T: std::fmt::Display {
    fn calculate(&self) {
        let d = ((self.x2 - self.x1).pow(2) +  (self.y2 - self.y1).pow(2)).sqrt();
        println!("{}", d);
    }
}

fn main(){
    let p = Point {x1:1, y1:4, x2: 2, y2: 6};
    p.calculate();
}

cannot subtract `T` from `T`

struct Point {
    x: i32, y: i32
}

impl Point {
    fn calculate(p1:Point, p2:Point) {
        let d = ((p2.x - p1.x).pow(2) +  (p2.y - p1.y).pow(2)).sqrt();
        println!("{}", d);
    }
}

fn main(){
    let p1 = Point {x: 1, y: 4};
    let p2 = Point {x: 2, y: 6};
    calculate(p1, p2);
}

うーん、いまいちわからん…