我早些时候遇到了一个奇怪的情况。我写道:
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都是不可知的,所以我很想认为这是预期的行为,而不是直接提出错误。
我尝试四处搜寻,但没有任何类似的东西。
答案 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
确定所需的类型。