简体   繁体   English

是否有一种简洁的方法来定义内联特征实现?

[英]Is there a concise way to define a trait implementation inline?

At a high level, I want to create an object that holds an integer, and then be able to perform various comparisons (<, >, etc.) against numbers that are input as strings.在高层次上,我想创建一个包含 integer 的 object,然后能够对作为字符串输入的数字执行各种比较(<、> 等)。 I am trying to get as much duplicated code pulled out as possible.我正在尝试尽可能多地提取重复的代码。

I have code like the following:我有如下代码:

/// Implement some binary op, like < or >=
trait Comparison {
    fn compare(a: i32, b: i32) -> bool;
}

struct Checker {
    lhs: i32,
    op: Box<dyn Comparison>,
}
impl Checker {
    fn check(&self, rhs: &str) -> bool {
        let i_rhs = rhs.parse::<i32>();
        if self.op.compare(self.lhs, i_rhs) {
            do_stuff()
        }
    }
}

trait DataChecker {
    fn check(&self, rhs: &str) -> bool;
}

struct GreaterThanChecker {
    data: Checker,
}

impl DataChecker for GreaterThanChecker {
    fn check(&self, rhs: &str) -> bool {
        return self.data.check(rhs);
    }
}

impl GreaterThanChecker {
    fn new(lhs: i32) -> Self {
        Self {
            data: DataChecker {
                lhs: lhs,
                op: todo!("???"),
            },
        }
    }
}

At the moment, I am not seeing a better way to handle the ???目前,我没有看到更好的方法来处理??? above than defining高于定义

struct GreaterThanComparison {}
impl Comparison for GreaterThanComparison {
    fn compare(a: i32, b: i32) -> bool {
        a > b
    }
}

and then GreaterThanComparison {} in place of the ???然后用GreaterThanComparison {}代替??? above.以上。 There will also very similar structs for LessThan , GreaterThanOrEquals , etc. LessThanGreaterThanOrEquals等也会有非常相似的结构。

In Java, I could just write op: (a,b) -> a > b , which is much more concise.在 Java 中,我可以只写op: (a,b) -> a > b ,这样更简洁。 Is there something similar that could be done in Rust?在 Rust 中可以做类似的事情吗? Or other places where I could make things more concise?或者我可以让事情更简洁的其他地方?

As I was writing this, I realized that one answer is probably macros, but I am not familiar enough with them at this point to want to try to go down that path.在我写这篇文章的时候,我意识到一个答案可能是宏,但我现在对它们还不够熟悉,所以想尝试 go 沿着这条路走下去。

This answer is based on @EvilTak's comment.该答案基于@EvilTak 的评论。

Using Fn(...)->... will allow lambdas to work.使用Fn(...)->...将允许 lambdas 工作。 Lambdas are not Sized , so they need to be Box ed. Lambda 不是Sized ,所以它们需要被Box编辑。

struct Checker {
  lhs: i32,
  op: Box<dyn Comparison>
}

impl GreaterThanChecker {
  fn new(lhs: i32) -> Self {
     Self {
       data: DataChecker {
         lhs: lhs,
         op: Box::new(|a,b| a > b)
       }
     }
  }
}

impl Checker {
  fn check(&self, rhs: &str) -> bool {
    let i_rhs = rhs.parse::<i32>();
    // Need parentheses around self.op or else the compiler 
    // thinks we are trying to call the method named op, 
    // not the one stored in op
    if (self.op)(self.lhs, i_rhs) {
       do_stuff()
    }
  }
}

The Comparison classes then go away. Comparison类然后 go 离开。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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