如何声明可以将对稀疏向量的引用添加到一起的泛型函数? [重复]

问题描述 投票:3回答:1

我正在尝试使用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()编译,所以我有点迷失。

两个向量应该加在一起。

rust
1个回答
4
投票

确保函数上定义的特征边界与函数中使用的行为匹配。

firstsecond不是CsVec<T>,而是&CsVec<T>。在Rust,&X是与X不同的类型。您需要一个特征限制,表示您可以添加两个&CsVec<T>s并获得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>s,我将返回操作给我的任何类型”,你可以通过返回<&'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
}

在这种情况下,输出类型不必完全是CsVec<T>,但是当它出现时,它的工作方式与第一个版本相同。

有关

© www.soinside.com 2019 - 2024. All rights reserved.