我想到了以下問題:F# Unit of Measure, Casting without losing the measure type 請注意,我沒有試圖使用這個unbox代碼,我只是發現了一些奇怪的在回答問題時的行爲。F#'unbox float x'與'unbox int x'奇怪的編譯結果
爲什麼下面的代碼工作
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)
的代碼工作預計將在括號中,所以我想這一定是有些表達式求值/類型推理規則。這裏究竟發生了什麼,爲什麼在第二種情況下需要這些缺口?
Tomas的答案解釋了錯誤,但作爲一個側面說明,'unbox'並不是最好的方法來做到這一點。您應該使用'LanguagePrimitives.FloatWithMeasure <'u>',這意味着在.NET字節碼中沒有操作,而'unbox'則添加了一些運行時類型檢查,在這種情況下這不是必需的。 – Tarmil
@Tarmil,我意識到這一點。感謝您確認'FloatWithMeasure'是一個更好的選擇,但是(請參閱我對鏈接問題的回答)。你介意在那邊添加/確認一下嗎? –
哦,我沒有在你關聯的問題中看到你的帖子。所以我們幾乎說了同樣的事情:) – Tarmil