rust - 使用 IntoIterator 特性编写通用特性实现,但仅适用于不可变引用实现者

标签 rust traits

我正在定义一个接受 i: &I 的特征范围。我想用这个 i for 中的值循环。

例如:

struct Test;

trait Bar<I> {
    fn bar(&self, i: &I);
}

impl<T, I: IntoIterator<Item=T>> Bar<I> for Test {
    fn bar(&self, i: &I) {
        for x in i {
            println!("woo!");
        }
    }
}

fn main() {
    let vec = vec!(1, 2, 3);
    let test = Test;
    test.bar(&vec);
}

Playground link

这会导致错误:

<anon>:10:9: 12:10 error: the trait `core::iter::Iterator` is not implemented for the type `&I` [E0277] <anon>:10         for x in i { <anon>:11             println!("woo!"); <anon>:12         } <anon>:10:9: 12:10 help: see the detailed explanation for E0277 <anon>:10:9: 12:10 note: `&I` is not an iterator; maybe try calling `.iter()` or a similar method <anon>:10:9: 12:10 note: required by `core::iter::IntoIterator::into_iter` error: aborting due to previous error playpen: application terminated with error code 101

我正在尝试使用 Deref trait 想看看我是否可以得到一些东西,但无济于事。

我真的很想在函数定义中保留不可变引用,因为这个特征试图在许多类型上通用,并使用 Bar<&'a I> 定义其他实现。导致了其他一些与我的生活相关的问题,我也一直遇到这些问题。

最佳答案

I是一个 IntoIterator没有说任何关于 &I 的事情,例如x..y是一个 IntoIterator (因为它是一个 Iterator 而它们都是),但是 &(x..y)不是。

你特别想绑定(bind)&I , 幸运的是可以通过 where 来完成子句,例如

impl<I, T> Bar<I> for Test 
    where for<'a> &'a I: IntoIterator<Item = T>
{
    fn bar(&self, i: &I) {
        for x in i {
            println!("woo!");
        }
    }
}

for<'a>只是意味着“一生'a”,所以where条款是说 &I始终是 IntoIterator (只写 where &I: IntoIterator 是不够的)。

关于 T 有一些选择要做那里的参数,例如

  1. IntoIterator<Item = T>
  2. IntoIterator<Item = &'a T>
  3. 完全删除参数,只写IntoIterator

最佳选择取决于您使用它做什么。对于问题中的具体示例,我会选择 3,因为 Item类型根本不重要。数字 2 是有道理的,因为几乎所有类型都有 &T实现 IntoIterator将产生引用(它似乎也避免了编译器目前在推理生命周期内的通用量化方面遇到的大多数错误/一般困难,这达到了 1 和 3)。

关于rust - 使用 IntoIterator 特性编写通用特性实现,但仅适用于不可变引用实现者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34806203/

相关文章:

php - 特质中的变量

php - 如何避免冲突用于依赖注入(inject)的 PHP 特性

rust - 如何在 Rust 中使用 __builtin_clzll?

rust - 哪些条件会触发 "read_line"后跟 "expect"中的错误处理?

rust - 将Rust&str转换为&'static&str

c++ - 减少彼此紧密关联的模板参数

c++ - C+ +'s concepts and Rust' 的特质有什么异同?

groovy - 使用 Groovy 特征编写 Geb 页面

rust - 处理 std::borrow::Cow 的集合

collections - 如何通过获取可变变量的所有权来替换它的值?