在 Rust 中的迭代器上编写 sum 的通用实现
Writing generic implementation of sum on an iterator in Rust
我一直在学习 Rust,来自 Swift、C 和 C++ 背景。我觉得我对所有权、借用和特征有了基本的了解。为了练习一下,我决定在通用切片 [T]
上实现一个 sum
函数,其中 T
具有默认值并且可以添加到自身。
这是我得到的结果:
trait Summable {
type Result;
fn sum(&self) -> Self::Result;
}
impl<T> Summable for [T]
where
T: Add<Output = T> + Default,
{
type Result = T;
fn sum(&self) -> T {
let x = T::default();
self.iter().fold(x, |a, b| a + b)
}
}
编译器为 a + b
抱怨 expected type parameter T, found &T
。
我明白错误发生的原因,但不知道如何解决。是的,x
的类型是T
。它不能是 &T
因为,如果没有别的,如果切片是空的,那就是 returned 的值,我不能 return 对函数内部创建的东西的引用。另外,默认函数 return 是函数内部代码拥有的新值。说得通。是的,b
应该是对切片中值的共享引用,因为我不想使用它们(不是 T
)并且我不想改变它们(不是 &mut T
).
但这意味着我需要将 T
添加到 &T
,并且 return 添加 T
因为我正在 return 一个新值( sum) 将由调用者拥有。怎么样?
PS: 是的,我知道这个功能已经存在了。这是一个学习练习。
std::ops::Add
特征有一个可选的 Rhs
类型参数,默认为 Self
:
pub trait Add<Rhs = Self> {
type Output;
fn add(self, rhs: Rhs) -> Self::Output;
}
因为您从 T: Add<Output = T>
绑定中省略了 Rhs
类型参数,它默认为 T
:因此您可以在 a
中添加一个 T
,但不是 &T
.
要么指定 T: for<'a> Add<&'a T, Output = T>
; or else somehow obtain an owned T
from b
, e.g. via T: Copy
or T: Clone
.
我一直在学习 Rust,来自 Swift、C 和 C++ 背景。我觉得我对所有权、借用和特征有了基本的了解。为了练习一下,我决定在通用切片 [T]
上实现一个 sum
函数,其中 T
具有默认值并且可以添加到自身。
这是我得到的结果:
trait Summable {
type Result;
fn sum(&self) -> Self::Result;
}
impl<T> Summable for [T]
where
T: Add<Output = T> + Default,
{
type Result = T;
fn sum(&self) -> T {
let x = T::default();
self.iter().fold(x, |a, b| a + b)
}
}
编译器为 a + b
抱怨 expected type parameter T, found &T
。
我明白错误发生的原因,但不知道如何解决。是的,x
的类型是T
。它不能是 &T
因为,如果没有别的,如果切片是空的,那就是 returned 的值,我不能 return 对函数内部创建的东西的引用。另外,默认函数 return 是函数内部代码拥有的新值。说得通。是的,b
应该是对切片中值的共享引用,因为我不想使用它们(不是 T
)并且我不想改变它们(不是 &mut T
).
但这意味着我需要将 T
添加到 &T
,并且 return 添加 T
因为我正在 return 一个新值( sum) 将由调用者拥有。怎么样?
PS: 是的,我知道这个功能已经存在了。这是一个学习练习。
std::ops::Add
特征有一个可选的 Rhs
类型参数,默认为 Self
:
pub trait Add<Rhs = Self> {
type Output;
fn add(self, rhs: Rhs) -> Self::Output;
}
因为您从 T: Add<Output = T>
绑定中省略了 Rhs
类型参数,它默认为 T
:因此您可以在 a
中添加一个 T
,但不是 &T
.
要么指定 T: for<'a> Add<&'a T, Output = T>
; or else somehow obtain an owned T
from b
, e.g. via T: Copy
or T: Clone
.