简体   繁体   English

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

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

I don't quite understand why this is ok 我不太明白为什么这样可以

use std::num;

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

but this is failing 但这失败了

use std::num;

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

with error 有错误

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;
                 ^~~~~~~~

For the sake of context, this is what I'm trying to do (pi approximation): 出于上下文考虑,这就是我想要做的(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));
    }
}

I'm using 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)使用rustc 0.13.0-nightly (f09279395 2014-11-17 17:22:06 +0000)

Update: as of Rust 1.0.0-alpha, pow() function is now a method on Int trait, and Float trait also provides powf() and powi() methods for raising into floating point and integer powers, respectively. 更新:从Rust 1.0.0-alpha开始, pow()函数现在是Int特性的一种方法,而Float特性也提供了powf()powi()方法,分别用于提高浮点数和整数幂。 Also uint has been changed to usize . uint也已更改为usize Consequently, here's how power operation looks now: 因此,下面是电源操作的外观:

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

It is also possible to use floating point operations to operate directly on f64 : 也可以使用浮点运算直接在f64上进行f64

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

The basic idea of the answer, however, still holds: you still need to specify exact types on literals in order for the method to be found at all. 但是,答案的基本思想仍然成立:您仍然需要在文字上指定确切的类型,以便完全找到该方法。


Let's look on num::pow() signature: 让我们看一下num::pow()签名:

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

It requires that the first argument implements Int trait, and it will return the value of the same type as this first argument. 它要求第一个参数实现Int trait,并且它将返回与此第一个参数相同类型的值。 Int implementors are listed here : 这里列出 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

It means that this function will work for any of these types. 这意味着该功能将适用于所有这些类型。 Now, let's look to your examples. 现在,让我们看一下您的示例。

This works: 这有效:

use std::num;

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

because there are no ambiguities. 因为没有歧义。 Rust compiler correctly infers that num::pow() is invoked as num::pow::<int>() because you explicitly stated that p_ is int , which constrains num::pow() return type to int and hence its parameter should also be int . Rust编译器正确推断num::pow()被作为num::pow::<int>()调用,因为您明确声明p_int ,这将num::pow()返回类型限制为int ,因此其参数为也应该是int

In this case, however, there is an ambiguity: 但是,在这种情况下,存在歧义:

use std::num;

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

Integer literals are untyped, so the compiler does not know exact type of 16 . 整数文字是无类型的,因此编译器不知道16确切类型。 This is the error you see: it can't decide which implementation to use because there are several appropriate types. 这是您看到的错误:由于存在几种适当的类型,因此无法决定使用哪种实现。 You need to put the literal type explicitly: 您需要显式放置文字类型:

use std::num;

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

or 要么

use std::num;

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

and it will work. 它会工作。

This is type inference at play. 这是在起作用的类型推断。

Here is the signature of pow : 这是pow签名

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

In

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

The result is int , so therefore 16 is also int since they have the same type (according to the signature). 结果为int ,因此16也为int因为它们具有相同的类型(根据签名)。

In

num::pow(16, 2) as f64

however, you ask the result to be converted to f64 , but never precise from what it should convert. 但是,你问的结果转换为f64它应该转换什么永远精确。

If precising the type of the result is a problem (requiring additional variables), then you can either: 如果确定结果的类型存在问题(需要其他变量),则可以:

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

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

I would obviously note that precising the type of the argument is easier. 我显然会指出,确定参数的类型更为容易。

暂无
暂无

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

相关问题 Rust 无法推断通用特征 impl 的返回类型 - Rust unable to infer return type for generic trait impl Rust编译器无法推断有关泛型的足够信息 - Rust compiler unable to infer enough information about generic types 错误:无法推断出有关_的足够类型信息; 需要类型注释或通用参数绑定 - Error: unable to infer enough type information about `_`; type annotations or generic parameter binding required 从具有匹配项的Option中提取值会导致“无法推断出足够的类型信息……”错误 - Extracting value from Option with match gives “unable to infer enough type information…” error 为什么会出现“无法推断出有关`_`的足够类型信息”的错误信息 - Why is this erroring out with “unable to infer enough type information about `_`” Rust impl Trait 作为函数返回类型 - Rust impl Trait as function return type 如何在 Rust 中使用具有 `impl trait` 返回类型的 `Fn` trait? - How to use `Fn` trait with return type of `impl trait` in Rust? 编译器无法推断 `impl 的 object<trait> ` 在 Rust 中实现了另一个特征</trait> - Compiler cannot infer if an object of `impl <trait>` has impled another trait in Rust 无法推断出关于`_`的足够类型信息; 需要输入注释或通用参数绑定 - Unable to infer enough type information about `_`; type annotations or generic parameter binding required 无法推断出关于_的足够类型信息;需要输入注释或通用参数绑定 - Unable to infer enough type information about _; type annotations or generic parameter binding required
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM