[英]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.