在 Rust 中乘以特征实现

Multiply trait implementations in Rust

我正在尝试为特征 IDimOffset0Transformer 和 IDimOffset1Transformer 的不同泛型类型实现特征 IDimTransformer,但编译器给我错误

trait IDimTransformer {
    fn get_offset_x(&self, x: i32) -> i32;
    fn get_offset_z(&self, z: i32) -> i32;
}

trait IDimOffset0Transformer : IDimTransformer {}
trait IDimOffset1Transformer : IDimTransformer {}

impl<T: IDimOffset0Transformer> IDimTransformer for T {
    fn get_offset_x(&self, x: i32) -> i32 {
        return x;
    }

    fn get_offset_z(&self, z: i32) -> i32 {
        return z;
    }
}

impl<T: IDimOffset1Transformer> IDimTransformer for T {
    fn get_offset_x(&self, x: i32) -> i32 {
        return x - 1;
    }

    fn get_offset_z(&self, z: i32) -> i32 {
        return z - 1;
    }
}

使用示例

struct Layer {}
impl IDimOffset1Transformer for Layer{}

fn some_func(dim: &impl IDimTransformer, x: i32, z: i32) -> i32 {
    return dim.get_offset_x(x) + dim.get_offset_z(x);
}

fn some_func_1(layer: &Layer, x: i32, z: i32) -> i32 {
    return some_func(layer, x, z);
}

编译器错误

error[E0119]: conflicting implementations of trait `layer::IDimTransformer`:
  --> src/layer.rs:59:1
   |
49 | impl<T: IDimOffset0Transformer> IDimTransformer for T {
   | ----------------------------------------------------- first implementation here
...
59 | impl<T: IDimOffset1Transformer> IDimTransformer for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

我认为您要找的图案在生锈时看起来像这样:

trait Transformer {
    fn get_offset_x(x: i32) -> i32;
    fn get_offset_z(z: i32) -> i32;
}

struct Offset0Transformer;

impl Transformer for Offset0Transformer {
    fn get_offset_x(x: i32) -> i32 {
        x
    }

    fn get_offset_z(z: i32) -> i32 {
        z
    }
}

struct Offset1Transformer;

impl Transformer for Offset1Transformer {
    fn get_offset_x(x: i32) -> i32 {
        x - 1
    }

    fn get_offset_z(z: i32) -> i32 {
        z - 1
    }
}

struct Layer { x: i32, z: i32 };

impl Layer {
    fn add_transformed<T: Transformer>(&self) -> i32 {
        T::get_offset_x(self.x) + T::get_offset_z(self.z)
    }
}

fn main() {
    let layer = Layer { x: 5, z: 2 };
    let result = layer.add_transformed::<Offset1Transformer>();
    println!("got: {}", result);
}

不过大多数时候你不需要这个。仔细考虑您的代码试图做什么并考虑更简单的方法通常会使您的代码更小更好。