在字面表达式的参考资料中,我看到
如果令牌没有后缀,则表达式的类型由类型推断确定:
i32
.但是,我从以下代码中得到一个错误:
let i = (-100).abs();
error[E0689]: can't call method `abs` on ambiguous numeric type `{integer}`
为什么方法-调用歧义数字导致错误?不是推断为i32
的“-100”类型。
发布于 2022-08-26 14:13:58
让我们首先引用有关那一页 (强调地雷)的所有相关部分:
i32
.现在,这种描述可能会误导,因为动词“约束”是如何使用的。一个人通常熟悉受特征约束的泛型类型,但这种引用可能不会以这种方式解释。受约束和过度约束的类型是指对必须通过类型推断来考虑的类型施加额外要求的情况,这种情况在调用该类型的方法时发生。
因此,不,它不适用于任何类型的约束。这里是一个反例.
fn is_signed(x: impl num_traits::Signed) {
let _ = x.abs(); // can call abs thanks to Signed trait
}
fn main() {
is_signed(-5);
}
这段代码(游乐场)似乎“约束”了-5
,以要求对数字进行签名,而且由于我们有多个整数类型的Signed
实现,所以这应该是不明确的。,但实际上,它从Rust 1.63.0开始编译了。
另一个奇特的例子。
trait Foo {}
impl Foo for u8 {}
impl Foo for u16 {}
fn foo(_: impl Foo) {}
fn main() {
foo(5);
}
此代码(游乐场)不编译,但并不是因为您可能预期的原因:
error[E0277]: the trait bound `i32: Foo` is not satisfied
--> src/main.rs:9:5
|
9 | foo(5);
| ^^^ the trait `Foo` is not implemented for `i32`
|
= help: the following other types implement trait `Foo`:
u16
u8
note: required by a bound in `foo`
--> src/main.rs:6:16
|
6 | fn foo(_: impl Foo) {}
| ^^^ required by this bound in `foo`
据称,整数的类型推断机制适用于默认类型i32
,尽管惟一可能的实现是u8
和u16
。这将是另一种模棱两可的情况。
但是,当尝试调用与类型直接关联的方法时,情况显然是不同的,就像在(-100).abs()
中所做的那样。从调用方法abs
(它甚至存在于多个整数类型)开始,编译器就将该整数视为具有过约束类型,并根据该推理对齐出现静态类型错误。编译器对此提供了不同的解释,这体现在错误E0689中。
对模棱两可的数字类型调用一个方法。
在任何情况下,代码不编译的真正原因是编译器无法在特定情况下识别整数的类型,并且没有将整数类型默认为i32
。锈蚀引用不是语言的标准引用,可能是不完整的,也可能包含过时的信息。除了过度约束和欠约束的误导性概念外,引用中的描述与编写时编译器的行为相匹配。在这一点上,我们很可能只是处理另一个编译器的细微差别。
另请参阅:
https://stackoverflow.com/questions/73501732
复制相似问题