我已經遇到了這些錯誤before in a much more complex scenario。從那以後,我簡化了很多東西,並且有很長時間的工作代碼,直到我需要覆蓋Equals
。它使用了F#似乎不喜歡的內聯成員。使用內聯類型成員失敗,FS1114,FS1113,FS1116,FS1118
基本上,該方案可歸納爲以下代碼:
[<Flags>]
type MyType =
| Integer = 0b0001
| Float = 0b0010
module Test =
[<CustomEquality;NoComparison>]
type SomeType =
| Int of int64
| Float of float
override x.Equals other =
match other with
| :? SomeType as y ->
// following line throws on compiling this
match SomeType.getType x &&& SomeType.getType y with
| MyType.Integer -> int64 x = int64 y // highest type is integer (both are int)
| MyType.Float -> float x = float y // highest type is float (either is or both are float)
| _ -> false // impossible
| _ -> false
override x.GetHashCode() =
match x with Int i -> hash i | Float f -> hash f
static member inline op_Explicit(n: SomeType): float =
match n with
| Int i -> float i
| Float f -> f
static member inline op_Explicit(n: SomeType): int64 =
match n with
| Int i -> i
| Float f -> int64 f
static member inline getType x =
match x with
| Int _ -> MyType.Integer
| Float _ -> MyType.Float
以下錯誤提出了(這有點像我剛纔的問題而是涉及複雜的鴨子類型)。
錯誤FS1114:值「Test.SomeType.getType」被內嵌標記,但在優化環境沒有義務
錯誤FS1113:值「的getType」被內嵌標記,但其實現使用內部的或私人功能不足
警告FS1116:標記爲'inline'的值具有意外值
錯誤FS1118:未內聯標記爲'inline'的值'getType',可能是因爲遞歸值標記爲' inline'
現在,沒有遞歸值,並且目標類型是已知的(由於在匹配模式中隱式轉換爲SomeType
),所以我認爲沒有理由使這種內聯是不可能的。
有沒有人有這方面的想法?或者一個模式,包括內聯op_Explicit
(如果您刪除getType
,您將會得到這些錯誤),最好是getType
內聯?我知道我可以通過一個面向對象的層次結構來解決這個問題,但是我寧願使用這種方法,爲了清晰起見(類型系統是一個晶格,而不是層次結構)和性能(更早帶有內聯的版本顯示測試場景速度提高了4倍以上,並且速度很重要)。
在事後,下面,簡單的場景也會引發這些錯誤:
module Test =
type SomeType =
| Int of int64
| Float of float
static member MyEquals (x, other: SomeType) =
// following line throws on compiling this
float x = float other
static member inline op_Explicit(n: SomeType): float =
match n with
| Int i -> float i
| Float f -> f
static member inline op_Explicit(n: SomeType): int64 =
match n with
| Int i -> i
| Float f -> int64 f
當我刪除類型裝飾other: SomeType
,錯誤消失。我不知道爲什麼這很重要,因爲具有相同靜態推斷方法的較窄類型不應引起這個錯誤,我想。
而且由於override x.Equals
的類型註釋爲obj
,所以我沒有看到如何使用該知識(刪除類型裝飾)來幫助我。
您可以通過不使用'function'並使用顯式參數+'match'來解決此問題。函數產生一個值;值不能內聯。靜態成員inline getType x =匹配x與Int _ - > MyType.Integer | Float _ - > MyType.Float' – ildjarn
@ildjarn,感謝您的建議,但這並不會改變錯誤,嘗試它,並將其複製到FSI中。但是你是對的,有時'inline'與'function'(靜態成員)一起工作,有時不能(綁定),不知道爲什麼,[有一個功能請求允許內聯'let f = fun x - > ... '](HTTPS://fslang.uservoice。com/forums/245727-f-language/suggestions/6237585-allow-inline-keyword-in-the-case-let -f-fun-a),但那是另一回事。無論哪種方式,錯誤依然存在。 – Abel
@ildjarn,順便說一句,我更新了Q.(實施你的建議),以避免錯誤從何而來。沒有編譯,F#編輯器,推理和智能感知,不要抱怨。 – Abel