[英]Inconsistent processing of generic ParamArray argument in F#
在這個問題的背景下被發現這個看似不一致的行為可以在F#2.0和F#3.0 RC中重現:
type Heterogeneous =
static member Echo([<ParamArray>] args: Object[]) = args
type Generic =
static member Echo<'T>([<ParamArray>] args: 'T[]) = args
用法:返回:
Heterogeneous.Echo 0 // [|0|] OK
Generic.Echo 0 // [|0|] OK
Heterogeneous.Echo (0,1) // [|0; 1|] OK
Generic.Echo (0,1) // [|0; 1|] OK
Heterogeneous.Echo [|0|] // [|[|0|]|] OK?
Generic.Echo [|0|] // [|0|] OOPS!!
Heterogeneous.Echo ([|0|],[|1|])) // [|[|0|]; [|1|]|] OK
Generic.Echo ([|0|],[|1|])) // [|[|0|]; [|1|]|] OK
任何人都可以解釋觀察到的行為是否是一個錯誤或功能?
更新:這個相關的答案傳達了F#開發團隊的確認,到目前為止,在使用ParamArray
屬性處理泛型類型參數時存在一個錯誤。
這種情況有點令人困惑,因為當您使用數組作為標記有ParamArray
的參數的實際參數時,該語言會嘗試將其解釋為將數組傳遞給普通的數組類型參數(因此如果可能,它會忽略ParamArray
屬性) )。
在您的示例中,在第二種情況下可以這樣做:
Generic.Echo [|0|]
編譯器推斷'T
是int
等你傳遞int[]
到類型的參數int[]
因此編譯器會忽略ParamArray
屬性和方法只是獲取包含數組0
。
在另一種情況下,這是不可能的:
Heterogeneous.Echo [|0|]
該方法需要一個obj[]
類型的參數,並且參數的類型是int[]
,因此這兩種類型不能統一(關鍵是編譯器不會自動將int[]
轉換為obj[]
)。 由於這是不可能的,它會考慮ParamArray
屬性並嘗試將int[]
轉換為obj
並將其作為ParamArray
的成員傳遞 - 這是編譯器可以自動執行的轉換,因此您可以獲得所描述的結果。
如果您使用obj[]
作為參數調用Heterogeneous.Echo
,那么它的行為與Generic.Echo
類似。 例如:
Heterogeneous.Echo [| box 0 |]
如果您想了解詳細信息,請參閱第14.4節。 F#語言規范 。 但是,重載決策規則非常復雜,所以我沒有一個解釋這種行為的確切參考 - 只是上面的非正式解釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.