使用 Iterator::sum 时,必须在此上下文中知道类型 [英] Type must be known in this context when using Iterator::sum

查看:26
本文介绍了使用 Iterator::sum 时,必须在此上下文中知道类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个特征,该特征对 n-dim 空间中两点之间的欧几里德距离进行建模.这些点表示为 Vec.

I am trying to implement a trait that models the euclidean distance between 2 points in an n-dim space. The points are represented as 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) 的类型提示.

Logic tells me that there is no reason for this not to work. As far as I know, the type parser works top to bottom, so all the types should be known. I am using Intellij-Rust and up until the .map(|(xa, xb): (&u32, &u32)| the compiler got the types just fine, at least I believe it did since it was able to figure out and give type hints about (xa, xb) before I explicitly specified the type.

据我所知,当我使用 sum() 时,一切都会走下坡路.我很确定我遗漏了一些东西,因为类型解析器不太可能弄清楚某些 u32 的总和是另一个 u32 但它仍然给出了 type must be known in this context 处理.

As far as I can see, everything goes downhill when I use sum(). I'm pretty sure I'm missing something since it's pretty unlikely that the type parser wouldn't figure out that the sum of some u32s is another u32 but it still gives the type must be known in this context treatment.

我到底错过了什么?

推荐答案

我建议查看文档以了解新功能.Iterator::sum 定义为:

I recommend checking the documentation for new functions. Iterator::sum is defined as:

fn sum<S>(self) -> S
where
    S: Sum<Self::Item>, 

这意味着当返回类型 (S) 可以从迭代器的项中创建时,它可以在任何迭代器上调用.

This means that it can be called on any iterator when the return type (S) can be created from the items of the iterator.

这在概念上允许将 i8 数组相加为 i8i16i32等.这种灵活性是有代价的:您必须指定求和的类型:

This conceptually allows an array of i8s to be summed to an i8, an i16, i32, etc. This flexibility comes at a price: you have to specify what type to sum to:

.sum::<MyType>()

您还可以将结果存储在显式类型的变量中:

You can also stash the result in an explicitly typed variable:

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::sum 时,必须在此上下文中知道类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆