Rust 锈型推断奇异性

Rust 锈型推断奇异性,rust,type-inference,Rust,Type Inference,我之前遇到了一个奇怪的情况。我写道: if rand::random() < self.food_chance {...} 然而,这段代码可以编译 if self.food_chance > rand::random() {...} 我在想。这种行为有什么原因吗? 这甚至是故意的行为吗 我对类型推断理论略知一二,而且我知道大多数算法对lhs/rhs是不可知的,所以我倾向于认为这是预期的行为,而不是直接的bug 我试着四处搜索,但我从来没有得到任何接近这一点的东西。操作符是一种方法

我之前遇到了一个奇怪的情况。我写道:

if rand::random() < self.food_chance {...}
然而,这段代码可以编译

if self.food_chance > rand::random() {...}
我在想。这种行为有什么原因吗? 这甚至是故意的行为吗

我对类型推断理论略知一二,而且我知道大多数算法对lhs/rhs是不可知的,所以我倾向于认为这是预期的行为,而不是直接的bug


我试着四处搜索,但我从来没有得到任何接近这一点的东西。

操作符是一种方法的糖;性状的测定方法。调用该方法时,左侧作为
self
参数;这决定了使用的是
PartialOrd
的哪个实现。由于您可以将
PartialOrd
特性用于不同类型,并将
f32
作为右侧类型,因此只有在左侧类型已知的情况下才能唯一确定
PartialOrd
的实现。
PartialOrd
的这种实现反过来决定了从
rand::random

中所需的类型,这基本上是因为Rust无法推断接收器的类型。必须知道接收器的类型才能执行方法查找,并且

rand::random() < self.food_chance
接收器是左手操作数

在表达式中

self.food_chance > rand::random()
另一方面,接收器是已知的,因此Rust可以执行方法查找。它将只找到作为接收器的
f32
的单个实现,即
PartialOrd
,这反过来决定了右侧的类型。如果存在不同右侧类型的实现,Rust也无法推断这种情况下的类型


要理解Rust无法推断接收器的原因,请查看。第一步是基于接收方的类型构建候选类型列表。只有当您已经知道接收机的类型时,这一点才明显有效。

您认为可以有不同类型的接收机将
f32
作为右侧,而只有一种实现将
f32
作为左侧。正如你所看到的,这不是真的。只有一个实现将
f32
作为左侧,但也只有一个实现将
f32
作为右侧,因此我无法真正理解这个答案是如何解释不对称的。我的论点假设OP不会手动实现
f32
PartialOrd
,在这种情况下,OP应该提到这一点,因为这与问题相关。这就是编译器能够推断类型的原因。我没有声明只有一个
PartialOrd
的实现,左侧是
f32
。不过,您的示例很好地说明了您的答案。您是否知道这是语言的限制(否则无法解决),还是仅仅是当前实现的限制?@MatthieuM。当前的语言定义并不包含推断接收者类型的过程。方法查找过程的定义(参见答案中的链接)当然需要事先知道接收器的类型。如果我们想推断接收者的类型,我们需要为接收者未知的情况发明不同的方法查找语义。我想不出任何合理和一致的方法来定义语义;通过简单的名称查找(固有+可见特征)选择候选方法列表,然后对接收者和参数进行推理,以找到匹配的候选方法,如果存在任何歧义,则拒绝。“我不确定的是,是否有这样的情况:算法的复杂性会爆炸,使它实际上不可能解决。”@MatthieuM。你可能可以用这些语义定义一种语言,但它与Rust有很大的不同;只是在如何推断类型上有所不同。
std::cmp::PartialOrd::lt(&rand::random(), &self.food_chance);
self.food_chance > rand::random()