如何将&i32转换为f64?

8
我正在尝试解决Rust Book中本章末尾的练习(链接)
以下是代码示例:
fn mean(v: &Vec<i32>) -> f64 {
    let mut sum = 0.0;
    let mut count = 0.0;

    for val in v {
        sum += &f64::from(val);
        count += 1.0;
    }

    sum / count
}

fn main() {
    let v = vec![1, 2, 3, 4];

    println!("The mean is {}", mean(&v));
}

错误如下:
error[E0277]: the trait bound `f64: std::convert::From<&i32>` is not satisfied
 --> src/main.rs:6:17
  |
6 |         sum += &f64::from(val);
  |                 ^^^^^^^^^ the trait `std::convert::From<&i32>` is not implemented for `f64`
  |
  = help: the following implementations were found:
            <f64 as std::convert::From<f32>>
            <f64 as std::convert::From<i16>>
            <f64 as std::convert::From<i32>>
            <f64 as std::convert::From<i8>>
          and 3 others
  = note: required by `std::convert::From::from`

我也尝试使用 as 关键字,但没有帮助。


为什么不建议将String(&String)、Vec(&Vec)或Box(&Box)作为函数参数接受引用? - Shepmaster
2个回答

17

f64 只实现了 From for i32,而不是 &i32(它是对 i32 的引用)。要使其正常工作,您需要解引用 val

fn mean(v: &Vec<i32>) -> f64 {
    let mut sum = 0.0;
    let mut count = 0.0;

    for val in v {
        sum += f64::from(*val);
        count += 1.0;
    }

    sum / count
}

如果您尝试执行val as f64,则情况也是一样的,实际上,在这种情况下,您会得到一个更有帮助的错误消息:

如上所述。

error[E0606]: casting `&i32` as `f64` is invalid
 --> src/main.rs:6:16
  |
6 |         sum += val as f64;
  |                ---^^^^^^^
  |                |
  |                cannot cast `&i32` as `f64`
  |                help: dereference the expression: `*val`

这太棒了,我完全忘记了这件事。非常感谢你。 - Artsiom Shamsutdzinau
标记答案为正确,这对双方都有益!(以及谷歌搜索):) - aran
1
还要注意,您可以将v的类型更改为&[i32]i32slice),这在Rust中比引用Vec更符合惯用法,因为它使函数更加灵活。例如,它将允许您传递Vec的子部分,而不总是处理整个Vec - Joe Clay

3
你可以使用*val as f64对变量进行反引用。
fn mean(v: &Vec<i32>) -> f64 {
    let mut sum = 0.0;
    let mut count = 0.0;

    for val in v {
        sum += *val as f64;
        count += 1.0;
    }

    sum / count
}

fn main() {
    let v = vec![1, 2, 3, 4];

    println!("The mean is {}", mean(&v));
}

另一种做法

fn main() {
    let v = vec![1, 2, 3, 4];
    let mean: f64 = v.iter().map(|&val| val as f64).sum::<f64>() / v.len() as f64;

    println!("The mean is {}", mean);
}

不错的例子,我正在学这门语言,如果我理解了,那么 v.iter().map(|&val| val as i64).sum::<i64>() as f64 / v.len() as f64 就更好了。 - Daniele Cruciani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接