接口中的Tupled参数

时间:2014-11-27 13:13:11

标签: f#

有人可以解释这个F#的好奇心吗?

    type IFoo =
        abstract member Bar1: int * int -> int * int
        abstract member Bar2: int * int -> (int * int)
        abstract member Bar3: (int * int) -> int * int

    type Foo() = class end
        with 
        interface IFoo with
            member this.Bar1 (x, y) = (x, y)
            member this.Bar2 (x, y) = (x, y) // Same impl as Bar1 i.e. parentheses on RHS of -> in interface member definition are ignored
            // member this.Bar3 (x, y) = (x, y) // Compile error: "This override takes a different number of arguments to the corresponding abstract member"
            member this.Bar3 tuple = tuple // So, parentheses on LHS of -> in interface member definition *does* make a difference!

IFoo.Bar1IFoo.Bar3的定义之间的含义有何不同?

1 个答案:

答案 0 :(得分:10)

这里,输入类型可以描述两个不同的东西:元组或CLI方法的参数列表。

这对返回类型没有影响,因为此返回类型的唯一解释是元组。但是在参数列表中,您可以在采用两个参数的CLI方法或采用一个参数的CLI方法之间做出决定,该方法恰好是一个元组。后者用额外的括号表示。

这就是为什么你可以用一个参数实现Bar3,键入一个元组,其他(从F#3开始)是不可能的。

这也是双括号对单个括号产生影响的地方。如果Bar3不抽象,您可以通过将其声明为member this.Bar3 ((arg1, arg2))来强制执行元组输入。

方法参数列表具有其他功能,例如可选参数。所以:

type Test () =
    member t.BarA(a, ?b) = a
    member t.BarT((a, ?b)) = a // Error

最后一行给出了错误"只允许在类型成员"上使用可选参数,因为b现在是元组模式的一部分,而不是方法参数中的参数列表。