在Rust中接受&Vec<T>和&Vec<&T>的函数

4
在我的结构体中,我有一个名为from的函数,它接受一个类型为 T 的元素的共享引用向量,并执行一些初始化操作。
fn from(t: &Vec<T>) -> () {
    // ...
    for a in t {
        // ...
    }
    for a in t {
        // ...
    }
}

我还有一个函数from_partial,它首先对&Vec<T>进行一些过滤,并希望将这个减少的元素列表传递给from。我不想克隆,所以from_partial构造了向量作为Vec<&T>而不是Vec<T>。我也不想在from中重复逻辑,因为它只需要循环遍历向量并获取一个&T存储在某个地方。
在我的具体类型示例中,我可以将&Vec<&Bar>&Vec<Bar>都分配给from
let a: &Vec<&Bar> = &test.iter().collect();
let b: &Vec<Bar> = test;
Foo::from(a); // can assign &Vec<&Bar>
Foo::from(b); // can assign &Vec<Bar>

然而,在使用泛型时,我却无法这样做:

fn from_partial(t: &Vec<T>) -> () {
    // Here a function is called that does some filtering on &Vec<T>
    // and returns &Vec<&T>, but omitting for brevity.
    let example: &Vec<&T> = &t.iter().collect();
    Self::from(example); // cannot assign &Vec<&T> to &Vec<T>?
}

这是MVCE(播放器)(请参见Playground)。
struct Foo<T> {
    t: T,
}
struct Bar {}

impl<T> Foo<T> {
    fn from(t: &Vec<T>) -> () {
        let mut v = Vec::new();
        for a in t {
            // ...
            v.push(Foo { t: a })
        }
        for a in t {
            // ...
            v.get(0);
        }
    }

    fn from_partial(t: &Vec<T>) -> () {
        // Here a function is called that does some filtering on &Vec<T>
        // and returns &Vec<&T>, but omitting for brevity.
        let example: &Vec<&T> = &t.iter().collect();
        Self::from(example); // cannot assign &Vec<&T> to &Vec<T>?
    }
}

fn main() {}

fn test(test: &Vec<Bar>) {
    let a: &Vec<&Bar> = &test.iter().collect();
    let b: &Vec<Bar> = test;
    Foo::from(a); // can assign &Vec<&Bar>
    Foo::from(b); // can assign &Vec<Bar>
}

有没有任何我可以添加在T上的约束条件,使这成为可能?基本上可以防止我在 from 两次完全重复相同的逻辑。

相关问答:如何编写一个接受借用或拥有元素的 Vec 的函数?,该回答更直接地回答了标题,因为这里的问题是对泛型类型的简单错误应用。 - kmdreko
1个回答

5
您需要用Foo::from(example);替换Self::from(example);
考虑到TBar,那么您的from_partial调用接受&Vec<Bar>。问题在于Self代表的是Foo::<Bar>,但您正在尝试使用&Bar调用from,也就是说您需要Foo::<&Bar>
fn from_partial(t: &Vec<T>) -> () {
    let example: &Vec<&T> = &t.iter().collect();
    Foo::from(example);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接