< 返回版块

sstudioer 发表于 2021-02-05 09:37

Tags:rust 泛型如何能够实现C++这种模式?

这是C++的源码, 我想实现类似的功能, 用RUST如何实现? // template <typename A, typename B>

#include <iostream>

using namespace std;

class Rect{
public:
    int x;
    int y;
    int width;
    Rect(){
        this->x = 10;
    };
};

class Circle{
public:
    int x;
    int y;
    int radius;
    Circle(){
        this->x = 10;
    };
};


template <typename A, typename B>
bool collide(A const& a,  B const& b) {    // 支持任何形状检测碰撞; 我想实现的功能.
    if(a.x == b.x){
        return true;
    }
    return false;

}

int main() {
    Circle a;
    Rect b;
    collide(a,b);
    std::cout << "text" << collide(a,b) << std::endl;
}

评论区

写评论
作者 sstudioer 2021-02-21 17:54

我只是举例子, 实际场景非常复杂;
用trait 重复代码太多. 用宏似乎更好些. rust 泛型太短板;

--
👇
hubaihua

hubaihua 2021-02-05 17:53
enum Shape {
  Rect { x: i32, y: i32, width: usize },
  Circle { x: i32, y: i32, radius: usize },
}

trait Collide {
  fn collide(&self, other: &Self) -> bool;
}

impl Collide for Shape {
  fn collide(&self, other: &Shape) -> bool {
    let l = match self {
      Shape::Rect { x, .. } => x,
      Shape::Circle { x, .. } => x,
    };
    let r = match other {
      Shape::Rect { x, .. } => x,
      Shape::Circle { x, .. } => x,
    };
    l == r
  }
}

fn collide_test() {
  let rect = Shape::Rect {
    x: 10,
    y: 20,
    width: 5,
  };
  let circle = Shape::Circle {
    x: 30,
    y: 40,
    radius: 10,
  };
  println!("collide: {}", rect.collide(&circle));
}

hubaihua 2021-02-05 17:38

果真可以了

--
👇
坚果修补匠: 这个回复的形式是markdown文档。写代码就用```Rust 和```把代码包裹起来就行了


👇
hubaihua: 怎么调整排版啊?我写评论就是一个大大的输入框和一个发送按钮,代码不知道怎么排版

坚果修补匠 2021-02-05 17:09

这个回复的形式是markdown文档。写代码就用```Rust 和```把代码包裹起来就行了


👇
hubaihua: 怎么调整排版啊?我写评论就是一个大大的输入框和一个发送按钮,代码不知道怎么排版

hubaihua 2021-02-05 16:16

怎么调整排版啊?我写评论就是一个大大的输入框和一个发送按钮,代码不知道怎么排版

hubaihua 2021-02-05 15:59

用枚举来完成

enum Shape { Rect { x: i32, y: i32, width: usize }, Circle { x: i32, y: i32, radius: usize }, }

trait Collide { fn collide(&self, other: &Self) -> bool; }

impl Collide for Shape { fn collide(&self, other: &Shape) -> bool { let l = match self { Shape::Rect { x, .. } => x, Shape::Circle { x, .. } => x, }; let r = match other { Shape::Rect { x, .. } => x, Shape::Circle { x, .. } => x, }; l == r } }

作者 sstudioer 2021-02-05 13:16

thanks; 这种接口实现好复杂;

johnmave126 2021-02-05 11:01

我感觉这种模式一般是这样

/// 一个表示可以跟`T`进行碰撞检测的trait
trait Collide<T> {
    fn collide(&self, other: &T) -> bool;
}

然后比如你现在的检测

struct Rect {
    x: i32,
    y: i32,
    width: usize,
}

struct Circle {
    x: i32,
    y: i32,
    radius: usize,
}

impl Collide<Rect> for Circle {
    fn collide(&self, other: &Rect) -> bool {
        self.x == other.x
    }
}

impl Collide<Circle> for Rect {
    fn collide(&self, other: &Circle) -> bool {
        other.collide(&self)
    }
}

然后就可以

fn main() {
    let rect = Rect {
        x: 10,
        y: 0,
        width: 10,
    };
    let circle = Circle {
        x: 10,
        y: 0,
        radius: 10,
    };
    println!("{}", rect.collide(&circle));
}

有一个缺点就是没办法通过实现一个方向来自动impl另一个方向,如果有foreign type的话有点麻烦。主要是泛型自动实现会被认为是conflict implementation,暂时没想到更好的办法

作者 sstudioer 2021-02-05 10:34

--
👇
snylonue: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3ec5ae7791c458cee4296113a516d998

写得不怎么样,仅供参考

thanks; 这种接口实现好复杂;

snylonue 2021-02-05 10:18

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3ec5ae7791c458cee4296113a516d998

写得不怎么样,仅供参考

1 共 10 条评论, 1 页