我正在尝试使用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()
可以编译,所以我有点迷路了。
两个向量应加在一起。
答案 0 :(得分:4)
请确保在函数中定义的特征范围与在函数中使用的行为相匹配。
first
和second
不是CsVec<T>
,而是&CsVec<T>
。在Rust中,&X
与X
是不同的类型。您需要一个特征绑定,它可以添加两个&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
}
,但在输出类型时,其输出方式与第一个版本相同。