使用 Iterator::sum 时,在此上下文中必须知道类型
Type must be known in this context when using Iterator::sum
我正在尝试实现一个特征,该特征对 n-dim space 中两点之间的欧氏距离进行建模。这些点表示为 Vec<u32>
.
pub trait Point {
fn euclidean_to(&self, other: Vec<u32>) -> f64;
}
impl Point for Vec<u32> {
fn euclidean_to(&self, other: Vec<u32>) -> f64 {
(self.iter()
.zip(other.iter())
.map(|(xa, xb): (&u32, &u32)| (xa - xb).pow(2))
.sum() as f64)
.sqrt()
}
}
逻辑告诉我,这没有理由不起作用。据我所知,类型解析器从上到下工作,因此所有类型都应该是已知的。我正在使用 Intellij-Rust,直到 .map(|(xa, xb): (&u32, &u32)|
编译器得到的类型都很好,至少我相信它做到了,因为它能够在我明确指定之前找出并给出关于 (xa, xb)
的类型提示方式。
据我所知,当我使用 sum()
时,一切都会走下坡路。我很确定我遗漏了一些东西,因为类型解析器不太可能不知道一些 u32
s 的总和是另一个 u32
但它仍然给出 type must be known in this context
治疗。
我到底错过了什么?
我建议查看新功能的文档。 Iterator::sum
定义为:
fn sum<S>(self) -> S
where
S: Sum<Self::Item>,
这意味着当可以从迭代器的项目创建 return 类型 (S
) 时,它可以在任何迭代器上调用。
这在概念上允许将 i8
的数组相加为 i8
、i16
、i32
等。这种灵活性是有代价的:您必须指定要求和的类型:
.sum::<MyType>()
您还可以将结果存储在明确类型化的变量中:
fn euclidean_to(&self, other: Vec<u32>) -> f64 {
let x: u32 = self.iter()
.zip(other)
.map(|(xa, xb)| (xa - xb).pow(2))
.sum();
(x as f64).sqrt()
}
这与 Iterator::collect
完全相同。
我正在尝试实现一个特征,该特征对 n-dim space 中两点之间的欧氏距离进行建模。这些点表示为 Vec<u32>
.
pub trait Point {
fn euclidean_to(&self, other: Vec<u32>) -> f64;
}
impl Point for Vec<u32> {
fn euclidean_to(&self, other: Vec<u32>) -> f64 {
(self.iter()
.zip(other.iter())
.map(|(xa, xb): (&u32, &u32)| (xa - xb).pow(2))
.sum() as f64)
.sqrt()
}
}
逻辑告诉我,这没有理由不起作用。据我所知,类型解析器从上到下工作,因此所有类型都应该是已知的。我正在使用 Intellij-Rust,直到 .map(|(xa, xb): (&u32, &u32)|
编译器得到的类型都很好,至少我相信它做到了,因为它能够在我明确指定之前找出并给出关于 (xa, xb)
的类型提示方式。
据我所知,当我使用 sum()
时,一切都会走下坡路。我很确定我遗漏了一些东西,因为类型解析器不太可能不知道一些 u32
s 的总和是另一个 u32
但它仍然给出 type must be known in this context
治疗。
我到底错过了什么?
我建议查看新功能的文档。 Iterator::sum
定义为:
fn sum<S>(self) -> S
where
S: Sum<Self::Item>,
这意味着当可以从迭代器的项目创建 return 类型 (S
) 时,它可以在任何迭代器上调用。
这在概念上允许将 i8
的数组相加为 i8
、i16
、i32
等。这种灵活性是有代价的:您必须指定要求和的类型:
.sum::<MyType>()
您还可以将结果存储在明确类型化的变量中:
fn euclidean_to(&self, other: Vec<u32>) -> f64 {
let x: u32 = self.iter()
.zip(other)
.map(|(xa, xb)| (xa - xb).pow(2))
.sum();
(x as f64).sqrt()
}
这与 Iterator::collect
完全相同。