Rust类型推理奇怪

sap*_*hie 4 type-inference rust

我早些时候遇到了一个奇怪的情况.我写:

if rand::random() < self.food_chance {...}
Run Code Online (Sandbox Code Playgroud)

(self.food_chance属于类型f32)

我得到了一个类型推理错误:

   |
71 |             if rand::random() < self.food_chance {
   |                ^^^^^^^^^^^^ cannot infer type for `T`
Run Code Online (Sandbox Code Playgroud)

但是这段代码编译

if self.food_chance > rand::random() {...}
Run Code Online (Sandbox Code Playgroud)

而且我想知道.这种行为有原因吗?它甚至是预期的行为吗?

我对类型推理理论有一点了解,我知道大多数算法都与lhs/rhs无关,所以我很想把它看成是预期的行为而不是直接的bug.

我试着四处寻找,但我从来没有接近过这个.

Sve*_*ach 7

这基本上是因为Rust无法推断出接收器的类型.必须知道接收器的类型才能执行方法查找,从那时起

rand::random() < self.food_chance
Run Code Online (Sandbox Code Playgroud)

相当于

std::cmp::PartialOrd::lt(&rand::random(), &self.food_chance);
Run Code Online (Sandbox Code Playgroud)

接收器是左手操作数.

在表达中

self.food_chance > rand::random()
Run Code Online (Sandbox Code Playgroud)

另一方面,接收器是已知的,因此Rust可以执行方法查找.它只能找到f32作为接收器的单个实现,即PartialOrd<f32>,然后又确定右侧的类型.如果有不同的右侧类型的实现,Rust也无法在这种情况下推断出类型.

要理解为什么 Rust无法推断接收器,请看看Rust的方法查找过程如何工作的.第一步是根据接收器的类型构建候选类型列表.这个显而易见的只有在您已经知道接收器的类型时才有效.