如何扩展在另一个板条箱中定义的特征?

发布于 2025-02-11 13:13:21 字数 407 浏览 1 评论 0 原文

我想创建一种新的迭代方法,例如:

let test_data = vec![1,2,3,1,1,1,1];
let indexes_with_val_1 = test_data.iter().find_all(|element| element == 1).unwrap();

assert_eq!(indexes_with_val_1, vec!(0,3,4,5,6));

因此,从本质上讲,我想在 std :: iter :: iterator :: iterator 特征上添加一个新方法,但找不到适用于此的

示例这不是问题,因为我的功能可以正常工作,所以我只想能够像代码示例那样使用它以获得更好的人体工程学。

I want to create a new iterator method such as:

let test_data = vec![1,2,3,1,1,1,1];
let indexes_with_val_1 = test_data.iter().find_all(|element| element == 1).unwrap();

assert_eq!(indexes_with_val_1, vec!(0,3,4,5,6));

So essentially I want to add a new method to the std::iter::Iterator trait but can't find examples that work for this

The logic is not an issue as I have a free function which works fine, I just would like to be able to use it as I have in the code example for better ergonomics.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最舍不得你 2025-02-18 13:13:21

您可以使用称为迭代特征,但是您可以编写一个新的特征。这就是我们要做的。

  1. 编写一个新的特征, iteratorext ,其中包含您的自定义方法。
  2. 为任何实现 Iterator 的类型编写一个blanket impl Inlph 。
  3. 导入 iteratorext 以访问您的扩展功能。

例如,我们可以在迭代器中添加一个名为 my_extension 的简单函数,因此

trait IteratorExt {

  fn my_extension(self) -> Self;

}

impl<T: Iterator> IteratorExt for T {

  fn my_extension(self) -> Self {
    println!("Hey, it worked!");
    self
  }

}

pub fn main() {
  let x = vec!(1, 2, 3, 4);
  let y = x.iter().my_extension().map(|x| x + 1).collect::<Vec<_>>();
  println!("{:?}", y);
}

唯一的缺点是您必须导入新特征才能使用它。因此,如果您想在另一个文件中使用 my_extension ,则必须专门导入 iteratorext 才能这样做。

以我的经验,生锈社区在某种程度上有所分歧,这是合法的练习还是要避免的攻击,因此您的里程可能会有所不同。

You can use a design pattern called extension traits. You can't extend the Iterator trait, but you can write a new one. Here's what we're going to do.

  1. Write a new trait, IteratorExt, which has your custom method in it.
  2. Write a blanket impl that implements IteratorExt for any type that implements Iterator.
  3. Import IteratorExt to get access to your extension function.

For example, we can add a simple function called my_extension to iterators like so

trait IteratorExt {

  fn my_extension(self) -> Self;

}

impl<T: Iterator> IteratorExt for T {

  fn my_extension(self) -> Self {
    println!("Hey, it worked!");
    self
  }

}

pub fn main() {
  let x = vec!(1, 2, 3, 4);
  let y = x.iter().my_extension().map(|x| x + 1).collect::<Vec<_>>();
  println!("{:?}", y);
}

The only downside is that you have to import the new trait to use it. So if you want to use my_extension in another file, you have to import IteratorExt specifically in order to do so.

In my experience, the Rust community is somewhat divided on whether this is legitimate practice or whether it's a hack to be avoided, so your mileage may vary.

家住魔仙堡 2025-02-18 13:13:21

存在扩展特质模式为此。

这个想法是您创建一个特征,通常由惯例命名为 traitext ,并为所有实现特质

pub trait IteratorExt {
    fn my_iterator_extension(&self);
}

impl<I: Iterator + ?Sized> IteratorExt for I {
    fn my_iterator_extension(&self) {
        // Do work.
    }
}

my_iterator.my_iterator_extension();

There exist the extension trait pattern for that.

The idea is that you create a trait, usually named TraitExt by convention, and implement it for all implementations of Trait:

pub trait IteratorExt {
    fn my_iterator_extension(&self);
}

impl<I: Iterator + ?Sized> IteratorExt for I {
    fn my_iterator_extension(&self) {
        // Do work.
    }
}

my_iterator.my_iterator_extension();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文