我正在尝试实现一个特征,该特征模拟n-dim空间中2个点之间的欧氏距离。这些点表示为library(tidyverse)
tbl <- tribble(
~one, ~two, ~three, ~type,
"x", "x", "", "chocolate",
"x", "", "", "vanilla",
"x", "x", "", "strawberry"
) %>%
mutate_at(vars(one:three), function(x) ifelse(x == "", NA_character_, x)) %>%
gather(key = "number", value = "x", one:three) %>%
rowid_to_column() %>%
spread(key = number, value = x) %>%
arrange(type) %>%
filter(!(is.na(one) & is.na(two) & is.na(three))) %>%
select(one, two, three, type) %>%
print()
# A tibble: 5 x 4
one two three type
<chr> <chr> <chr> <chr>
1 x NA NA chocolate
2 NA x NA chocolate
3 x NA NA strawberry
4 NA x NA strawberry
5 x NA NA vanilla
。
Vec<u32>
逻辑告诉我没有理由不这样做。据我所知,类型解析器从上到下工作,因此应该知道所有类型。我正在使用Intellij-Rust直到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()
}
}
编译器得到的类型很好,至少我相信它确实如此,因为它能够在我明确指定之前找出并给出关于.map(|(xa, xb): (&u32, &u32)|
的类型提示类型。
据我所知,当我使用(xa, xb)
时,一切都会走下坡路。我很确定我错过了一些东西,因为类型解析器不太可能发现某些sum()
的总和是另一个{{1}但它仍然提供u32
治疗。
我到底错过了什么?
答案 0 :(得分:2)
我建议查看文档以了解新功能。 Iterator::sum
定义为:
fn sum<S>(self) -> S
where
S: Sum<Self::Item>,
这意味着当可以从迭代器的项创建返回类型(S
)时,可以在任何迭代器上调用它。
这在概念上允许将i8
s的数组求和为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
完全相同。