如何声明可以将对稀疏向量的引用加在一起的泛型函数?

时间:2019-02-15 13:53:27

标签: rust

我正在尝试使用the sprs crate(版本0.6.3)来处理稀疏向量。我想将两个向量加在一起。 我从实现Add特性开始,然后将其简化为实现功能。最后,我将问题归结为一个简单的通用函数。

// This works: the scalar type `u64` is fixed here
fn adder(first: &CsVec<u64>, second: &CsVec<u64>) -> CsVec<u64> {
    first + second
}

// When I try to make the scalar type generic, it doesn't work
fn adder2<T>(first: &CsVec<T>, second: &CsVec<T>) -> CsVec<T>
where
    CsVec<T>: Add,
    T: Add + Debug,
{
    first + second
}

第一个版本可以编译,但是我想知道为什么第二个版本不能编译。我收到此错误消息:

error[E0369]: binary operation `+` cannot be applied to type `&sprs::sparse::CsVecBase<std::vec::Vec<usize>, std::vec::Vec<T>>`
  --> libp3prime/src/lib/datacache.rs:62:5
   |
62 |     first + second
   |     ^^^^^^^^^^^^^^
   |
   = note: an implementation of `std::ops::Add` might be missing for `&sprs::sparse::CsVecBase<std::vec::Vec<usize>, std::vec::Vec<T>>`

我不太了解错误消息。我知道您可以一起添加两个CsVecs,因为adder()可以编译,所以我有点迷路了。

两个向量应加在一起。

1 个答案:

答案 0 :(得分:4)

请确保在函数中定义的特征范围与在函数中使用的行为相匹配。

firstsecond不是CsVec<T>,而是&CsVec<T>。在Rust中,&XX是不同的类型。您需要一个特征绑定,它可以添加两个&CsVec<T>并获得一个CsVec<T>作为输出:

fn adder2<'a, T>(first: &'a CsVec<T>, second: &'a CsVec<T>) -> CsVec<T>
where
    &'a CsVec<T>: Add<Output = CsVec<T>>,
{
    first + second
}

在此示例中,T上没有限制。

在这种情况下,'a生存期参数已传递给函数。有时,在函数的引用 中定义绑定特征是很有用的,例如,对局部变量的引用使用+。在这种情况下,您可能想使用高阶特征绑定 for<'a> &'a CsVec<T>: Add<Output = CsVec<T>>。有关更多信息,请参见下面的链接问题。

Lukas Kalbertodt指出,有时说“我只想添加两个&CsVec<T>,然后我将返回该操作给我的任何类型”可能会更灵活,您可以通过返回{{ 1}}:

<&'a CsVec<T> as Add>::Output

在这种情况下,输出类型不必精确地为fn adder2<'a, T>(first: &'a CsVec<T>, second: &'a CsVec<T>) -> <&'a CsVec<T> as Add>::Output where &'a CsVec<T>: Add, { first + second } ,但在输出类型时,其输出方式与第一个版本相同。

相关