锈类型推断奇数

时间:2018-11-25 12:26:32

标签: rust type-inference

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

if rand::random() < self.food_chance {...}

self.food_chance的类型为f32

我收到类型推断错误:

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

但是此代码可以编译

if self.food_chance > rand::random() {...}

我就纳闷了。有这种行为的原因吗? 它甚至是预期的行为吗?

我对类型推断理论有所了解,而且我知道大多数算法对lhs / rhs都是不可知的,所以我很想认为这是预期的行为,而不是直接提出错误。

我尝试四处搜寻,但没有任何类似的东西。

2 个答案:

答案 0 :(得分:7)

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

rand::random() < self.food_chance

等同于

std::cmp::PartialOrd::lt(&rand::random(), &self.food_chance);

接收者是左操作数。

在表达式中

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

要了解为什么 Rust无法推断接收者,请查看how Rust's method lookup process works。第一步是根据接收者的类型建立候选类型列表。仅当您已经知道接收器的类型时,这种情况才有效。

答案 1 :(得分:3)

>运算符是一种方法的代名词; partial_cmp特征的PartialOrd方法。该方法以左侧的self参数调用;这确定使用PartialOrd的实现。因为您可以使用PartialOrd作为右侧类型来实现不同类型的f32特性,所以只有在左侧类型为PartialOrd时,才能唯一确定PartialOrd的实现。众所周知。 rand::random的此实现又从Public Class FadeInTimer Inherits Timer Public Sub New() MyBase.New() Me.Enabled = False Me.Interval = 75 End Sub Private Sub FadeInTimer_Tick(sender As Object, e As EventArgs) Handles Me.Tick Dim workingAreaWidth As Integer = Screen.PrimaryScreen.WorkingArea.Width - Me.Width Me.Opacity += 0.1 If Not Me.Location.X <= workingAreaWidth Then Me.Location = New Point(Me.Location.X - 30, Me.Location.Y) End If Me.Refresh() If Me.Opacity = 1 Then Me.Stop() End If End Sub End Class 确定所需的类型。