【发布时间】:2014-03-14 21:54:35
【问题描述】:
这是在我查看以下问题时出现的:F# Unit of Measure, Casting without losing the measure type 请注意,我并没有尝试使用此拆箱代码,我只是在回答问题时发现了一些奇怪的行为。
为什么下面的代码会起作用
let intToFloat (x:int<'u>) : float<'u> = unbox float x
intToFloat 1<second>
虽然这会产生 System.InvalidCastException:无法将类型“float32ToFloat@86-6”的对象转换为类型“Microsoft.FSharp.Core.FSharpFunc`2[System.Single,System.Double]”。 ?
let float32ToFloat (x:float32<'u>) : float<'u> = unbox float x
float32ToFloat 1.0f<second>
如果我在(float x) 周围加上括号,代码会按预期工作,所以我认为它一定是某种表达式评估/类型推断规则。这里到底发生了什么,为什么在第二种情况下需要括号?
【问题讨论】:
-
托马斯的回答解释了错误,但作为旁注,
unbox不是最好的方法。您应该使用LanguagePrimitives.FloatWithMeasure<'u>,它转换为.NET 字节码中的无操作,而unbox添加了一些在这种情况下不需要的运行时类型检查。 -
@Tarmil,我知道这一点。感谢您确认
FloatWithMeasure是一个更好的选择(请参阅我对链接问题的回答)。你介意在那里添加/确认吗? -
哦,我在您链接的问题中没有看到您的帖子。所以我们几乎说了同样的话:)
标签: f# type-inference units-of-measurement