>我有一个带有一个通用参数的基本函数:
let func<'T> (x:'T when 'T : (static member op_Explicit: 'T -> float) ) =
float x
为什么我会收到错误:"声明的类型参数'T 不能在这里使用,因为类型参数无法在编译时解析"
在此示例中,我提供了一个通用参数并将其约束为能够显式转换为浮点数,并且函数所做的所有函数都强制转换为浮点数,那么问题是什么? 我已经阅读了与 F# 中的泛型相关的所有 MSDN 文档,但它们似乎只是在兜圈子,与我在 Visual Studio 中看到的行为不符。 根据我的理解,使用单引号语法'T
适用于运行时泛型,而不是编译时泛型。
这就引出了我另一个问题。 我经常看到语法'T
和^T
混合在一起,有inline
和没有。 这违背了有关这些语法定义的 MSDN 文档。 我错过了什么吗?
此外,从文档中可以看出,似乎应该能够自动推断出对类型 'T
的op_Explicit
约束,而无需从以下位置进行任何类型注释:
let func x =
float x
但在这种情况下,推断x
的类型是int
的。
这里有一个可能会有所帮助的快速摘要。
你使用inline
、^T
和成员约束来编写奇怪的代码,"对于具有此临时 API 集的所有类型 T";这是不能直接在 .NET 中创作的代码(例如,你不能用 C# 编写它),它必须inline
,因为 F# 编译器可以在每个单独的调用站点上对特定类型进行内联/硬编码。 这是一个非常高级的功能,因此您不太可能找到太多有关它的文档/示例(并且错误诊断并不总是很好)。
您将'T
用于普通泛型,例如您在 C# 中执行的常见泛型操作。 这是一个主线方案。
请注意,在这两种情况下,通常都可以(/更好/更容易)让 F# 为你推断类型和泛型,而不是拼写出来。 例如
let inline f x = float x
Visual Studio 中的悬停提示f
表示已推断出适当的约束。
多亏了@ildjarn,我找到了答案:
从 http://msdn.microsoft.com/en-us/library/dd548046:
静态解析的类型参数主要与成员约束结合使用,成员约束是允许您指定类型参数必须具有一个或多个特定成员才能使用的约束。无法使用常规泛型类型参数创建此类约束。
Visual Studio似乎应该给出一个不同的错误,例如:"此处不能使用成员约束,因为'T 不是静态解析类型'或"成员约束只能与静态解析的类型参数结合使用。"