Rust:Trait RangeBounds 不能被做成一个对象

问题描述

我在尝试 Rust 时偶然发现了一个问题,这可能表明我对它的概念有更大的不理解。

我的目标是编写康威生命游戏的变体。我希望创建单元格或保持活动状态时的值不是硬编码,而是在结构中。我的第一次尝试是创建一个结构

use std::ops::Range;

struct Rules {
    be_born: Range<usize>,stay_alive: Range<usize>,}

impl Rules {
  pub fn new(be_born: Range<usize>,stay_alive: Range<usize>) -> Rules {
    Rules { be_born,stay_alive }
  }
}

let rules = Rules::new(2..4,3..6);

此对象稍后在迭代所有单元格的算法中使用。它工作正常,直到我还想在创建过程中允许其他类型的范围,例如 Rangeto (2..=3)。

我知道我可以将 struct Rules 重写为泛型。

use std::ops::RangeBounds;

struct Rules<BR: RangeBounds<usize>,AR: RangeBounds<usize>> {
    be_born: BR,stay_alive: AR,}

这反过来又会迫使我使我使用的所有算法也通用。仅仅包含两个简单的范围,这似乎是相当多的开销。

另一方面,我尝试将 RangeBounds 类型的变量直接包含到我的结构中的尝试都没有成功。我尝试了 &dyn RangeBounds<usize>Box<&dyn RangeBounds<usize>>,只是为了总是得到错误 E0038,我无法将这个特征变成一个对象。

是否有其他方法可以完成此操作,或者是否有其他一些我看不到的可行方法

预先感谢您的所有提示

解决方法

要获得广泛的答案,我们需要知道您在 be_bornstay_alive 字段上迭代的准确程度。但是为了解决您指出要使用不同类型范围的问题,最简单的方法是指定 be_bornstay_alive 字段都是返回 {{1} } 迭代时,又名 Iterable:

usize

这也将允许您将非范围但可迭代的类型分配给 Iterator<Item=usize>struct Rules<T,U> where T: Iterator<Item=usize>,U: Iterator<Item=usize> { be_born: T,stay_alive: U,} impl<T,U> Rules<T,U> where T: Iterator<Item=usize>,U: Iterator<Item=usize> { pub fn new(be_born: T,stay_alive: U) -> Self { Self { be_born,stay_alive } } } fn main() { let rule = Rules::new(2..4,3..6); let other_rule = Rules::new(2..=4,3..=6); let another_rule = Rules::new(2..=4,3..6); for x in rule.be_born { println!("born: {}",x); } for y in rule.stay_alive { println!("alive: {}",y); } } 字段。如果您只想限制范围类型,您可以将代码中的每个 be_born 替换为 stay_alive,这意味着“同时实现 Iterator<Item=usize>Iterator<Item=usize> + RangeBounds<usize> 的类型” .

有关 Iterator<Item=usize> 特征的进一步用法,请参阅 the book