繁体   English   中英

Rust错误:无法推断出足够的类型信息以定位特征的隐含形式

[英]Rust error: unable to infer enough type information to locate the impl of the trait

我不太明白为什么这样可以

use std::num;

fn main() {
    let mut p_: int = num::pow(16, 2);
    let mut p: f64 = p_ as f64;
}

但这失败了

use std::num;

fn main() {
    let mut p: f64 = num::pow(16, 2) as f64;
}

有错误

error: unable to infer enough type information to locate the impl of the trait `core::num::Int` for the type `_`; type annotations required
let mut p: f64 = num::pow(16, 2) as f64;
                 ^~~~~~~~

出于上下文考虑,这就是我想要做的(pi近似值):

fn main() {
    let mut pi: f64 = 0.0;
    let precision: int = 10;

    for i in range(0, precision) {
        let k = i as f64;
        let mut pi16: int = num::pow(16, i as uint);
        let mut p16: f64 = pi16 as f64;
        pi += 1.0/p16 * (4.0/(8.0 * k + 1.0) - 2.0/(8.0 * k + 4.0) - 1.0/(8.0 * k + 5.0) - 1.0/(8.0 * k + 6.0));
    }
}

rustc 0.13.0-nightly (f09279395 2014-11-17 17:22:06 +0000)使用rustc 0.13.0-nightly (f09279395 2014-11-17 17:22:06 +0000)

更新:从Rust 1.0.0-alpha开始, pow()函数现在是Int特性的一种方法,而Float特性也提供了powf()powi()方法,分别用于提高浮点数和整数幂。 uint也已更改为usize 因此,下面是电源操作的外观:

let mut p: f64 = 16us.pow(2) as f64;

也可以使用浮点运算直接在f64上进行f64

let mut p: f64 = 16.0.powi(2);

但是,答案的基本思想仍然成立:您仍然需要在文字上指定确切的类型,以便完全找到该方法。


让我们看一下num::pow()签名:

pub fn pow<T: Int>(base: T, exp: uint) -> T

它要求第一个参数实现Int trait,并且它将返回与此第一个参数相同类型的值。 这里列出 Int实现器:

impl Int for u8
impl Int for u16
impl Int for u32
impl Int for u64
impl Int for uint
impl Int for i8
impl Int for i16
impl Int for i32
impl Int for i64
impl Int for int

这意味着该功能将适用于所有这些类型。 现在,让我们看一下您的示例。

这有效:

use std::num;

fn main() {
    let mut p_: int = num::pow(16, 2);
    let mut p: f64 = p_ as f64;
}

因为没有歧义。 Rust编译器正确推断num::pow()被作为num::pow::<int>()调用,因为您明确声明p_int ,这将num::pow()返回类型限制为int ,因此其参数为也应该是int

但是,在这种情况下,存在歧义:

use std::num;

fn main() {
    let mut p: f64 = num::pow(16, 2) as f64;
}

整数文字是无类型的,因此编译器不知道16确切类型。 这是您看到的错误:由于存在几种适当的类型,因此无法决定使用哪种实现。 您需要显式放置文字类型:

use std::num;

fn main() {
    let mut p: f64 = num::pow(16u, 2) as f64;
}

要么

use std::num;

fn main() {
    let mut p: f64 = num::pow::<uint>(16, 2) as f64;
}

它会工作。

这是在起作用的类型推断。

这是pow签名

pub fn pow<T: Int>(base: T, exp: uint) -> T

let p: int = num::pow(16, 2);

结果为int ,因此16也为int因为它们具有相同的类型(根据签名)。

num::pow(16, 2) as f64

但是,你问的结果转换为f64它应该转换什么永远精确。

如果确定结果的类型存在问题(需要其他变量),则可以:

// precise the type at call site
num::pow::<i64>(16, 2)

// precise the type of the argument
num::pow(16i64, 2)

我显然会指出,确定参数的类型更为容易。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM