简体   繁体   中英

How can I use enum in a trait and implement trait on structs that are in the enum? Rust

I'm learning Rust so this might be a duplicate, since I'm still not sure how to search this. I tried to make a enum that contains different structs and since those structs have same methods but different implementation, I can't figure out how to properly write the types for the trait and the implementation. This is what I have so far:

struct Vector2 {
    x: f32,
    y: f32,
}

struct Vector3 {
    x: f32,
    y: f32,
    z: f32,
}

enum Vector {
    Vector2(Vector2),
    Vector3(Vector3),
}

trait VectorAdd {
    fn add(&self, other: &Vector) -> Vector;
}

impl VectorAdd for Vector2 {
    fn add(&self, other: &Vector2) -> Vector2 {
        Vector2 {
            x: self.x + other.x,
            y: self.y + other.y
        }
    }
}

This code does not compile, and the error messages don't make it clearer for me. Anyone can guide me how to write this properly? or if it's even possible?

Since you are using generics here, you don't need the enum to write the trait:

struct Vector2 {
    x: f32,
    y: f32,
}

struct Vector3 {
    x: f32,
    y: f32,
    z: f32,
}

trait VectorAdd {
    fn add(&self, other: &Self) -> Self;
}

impl VectorAdd for Vector2 {
    fn add(&self, other: &Vector2) -> Vector2 {
        Vector2 {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

impl VectorAdd for Vector3 {
    fn add(&self, other: &Vector3) -> Vector3 {
        Vector3 {
            x: self.x + other.x,
            y: self.y + other.y,
            z: self.z + other.z,
        }
    }
}

( playground )

You can implement the enum based on this definition:

enum Vector {
    Vector2(Vector2),
    Vector3(Vector3),
}

impl VectorAdd for Vector {
    fn add(&self, other: &Vector) -> Vector {
        match (self, other) {
            (Self::Vector2(a), Self::Vector2(b)) => Self::Vector2(a.add(b)),
            (Self::Vector3(a), Self::Vector3(b)) => Self::Vector3(a.add(b)),
            _ => panic!("invalid operands to Vector::add"),
        }
    }
}

Macros may help you if the number of variants gets large.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM