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

ᴘᴀɴ*_*ᴛɪs 4 generics rust

在我的结构中,我有一个from函数,它采用对类型元素向量的共享引用T并进行一些初始化。

fn from(t: &Vec<T>) -> () {
    // ...
    for a in t {
        // ...
    }
    for a in t {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我还有另一个函数from_partial,它首先执行一些过滤&Vec<T>,并希望将这个缩减的元素列表传递给from. 我不想克隆,因此from_partial将向量构造Vec<&T>为而不是Vec<T>。我也不想重复其中的逻辑,from因为所有需要做的就是循环向量并获取 a&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>
Run Code Online (Sandbox Code Playgroud)

但是,当使用泛型类型时,我无法这样做:

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>?
}
Run Code Online (Sandbox Code Playgroud)

这是 MVCE(游乐场):

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>
}
Run Code Online (Sandbox Code Playgroud)

我可以添加任何类型的约束来T使这成为可能吗?从根本上防止我重复完全相同的逻辑两次from

Val*_*tin 5

您需要替换Self::from(example);Foo::from(example);.

考虑一下TBar然后你的from_partial电话就接通了&Vec<Bar>。问题是Selfthen 代表Foo::<Bar>,但您正在尝试调用from&Bar即您需要Foo::<&Bar>

fn from_partial(t: &Vec<T>) -> () {
    let example: &Vec<&T> = &t.iter().collect();
    Foo::from(example);
}
Run Code Online (Sandbox Code Playgroud)