繁体   English   中英

F#中通用ParamArray参数的处理不一致

[英]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|]

编译器推断'Tint等你传递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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM