本文介绍了在F#泛型参数的ParamArray不一致的处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

被发现在这个问题这个看似不一致的行为可以被复制如下无论是在F#2.0和F#3.0 RC:

Being spotted in context of this question this seeminglyinconsistent behavior can be reproduced as following both in F#2.0 and F#3.0 RC:

type Heterogeneous =
    static member Echo([<ParamArray>] args: Object[]) = args

type Generic =  
    static member Echo<'T>([<ParamArray>] args: 'T[]) = args

Usage:                                                              Returns:

Usage:                                                              Returns:

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

任何人都可以解释,如果观察到的行为是一个错误或功能?

Can anyone explain if the observed behavior is a bug, or feature?

更新:相关答案通信从F#开发团队的确认,截至目前的错误已经发生的泛型类型参数的处理与 ParamArray参数属性。

UPDATE:This related answer communicates a confirmation from F# development team that as of now a bug has place in processing of generic type arguments with ParamArray attribute.

推荐答案

目前,此案略显混乱,因为当你使用一个数组作为一个实际的参数标有 ParamArray参数,语言尝试跨preT它,如果你是传球达阵,以一个正常的数组类型的参数(因此它忽略了 ParamArray参数属性,如果可能的话)。

The case is slightly confusing because when you use an array as an actual argument to a parameter marked with ParamArray, the language tries to interpret it as if you were passing array to a normal array-typed parameter (so it ignores the ParamArray attribute if possible).

在您的例子,这是可能的第二种情况:

In your example, this is possible in the second case:

Generic.Echo [|0|]

该编译器将指示'T INT 等你传递 INT [] 来类型的参数 INT [] 等编译器会忽略 ParamArray参数属性该方法只是获取包含数组 0

The compiler infers that 'T is int and so you're passing int[] to a parameter of type int[] and so the compiler ignores ParamArray attribute and the method simply gets an array containing 0.

在另一种情况下,这是不可能的:

In the other case, this is not possible:

Heterogeneous.Echo [|0|]

该方法需要类型的参数 OBJ []和参数的类型是 INT [] ,所以这两种类型无法统一(关键是编译器不会自动转换 INT [] OBJ [] )。由于这是不可能的,它认为 ParamArray参数属性,并尝试转换 INT [] OBJ ,并将其作为 ParamArray参数 - 这是一个转换编译器可以自动执行,所以你得到你所描述的结果。

The method expects a parameter of type obj[] and the type of the argument is int[], so the two types cannot be unified (the key is that the compiler does not automatically convert int[] to obj[]). Since this is not possible, it considers the ParamArray attribute and tries to convert int[] to obj and pass it as a member of ParamArray - this is a conversion that the compiler can automatically perform and so you get the result you described.

如果你叫 Heterogeneous.Echo OBJ [] 作为参数,那么它会表现得类似于 Generic.Echo 。例如:

If you called Heterogeneous.Echo with obj[] as an argument, then it would behave similarly to Generic.Echo. For example:

Heterogeneous.Echo [| box 0 |]

如果你想进入的细节,你可以看看节14.4。的 F#语言规范。但是,重载决策规则是pretty的复杂,所以我没有一个确切的参考,解释这种行为 - 只是一个非正式的解释,上述

If you want to go into details, you can look at section 14.4. of the F# language specification. However, the overload resolution rules are pretty complex and so I don't have an exact reference that explains this behaviour - just an informal explanation above.

这篇关于在F#泛型参数的ParamArray不一致的处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 07:01