区分具有可选参数的F#重载函数

7

F#允许重载函数仅通过可选参数来区分,例如:

type MyClass() = 
    member this.func(a: string, b:string) = "func(a,b)"
    member this.func(a: string, ?b:string) = "func(a,?b)"

你会如何称呼第一个函数?

1
你可以在任何函数中重命名第二个参数:`type MyClass() = member this.func(a: string, b:string) = "func(a,b)" member this.func(a: string, ?c:string) = "func(a,?c)"let test = MyClass()let arg1 = "2" let arg2 = "12"test.func(arg1, b = arg2) |> printfn "%s" //func(a,b) test.func(arg1, c = arg2) |> printfn "%s" //func(a,?c)` - FoggyFinder
1个回答

10
我认为如果两个重载函数仅因可选参数而不同,则没有明智的方法调用第一个函数。如评论中所述,使用此方法可能是设计上的错误,您应该重命名参数。
正如您可能已经注意到的那样,当您尝试使用 MyClass().func("A","B") 普通方式调用函数时,您会收到一个有关歧义的错误消息:

error FS0041: A unique overload for method 'func' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member MyClass.func : a:string * ?b:string -> string, member MyClass.func : a:string * b:string -> string

由于您可以为可选参数显式提供 Some 值,因此可以通过两种方式显式调用第二个重载(带或不带 ?b)。
MyClass().func("A")
MyClass().func("A",?b=Some "B")

出于好奇,我们发现可以通过静态成员约束调用第一个重载函数。这样做相当丑陋,您可能不应该这样做,但它会调用第一个重载函数:

let inline callFunc (o:^T) a b = 
  (^T : (member func : string * string -> string) (o, a, b)) 

callFunc (MyClass()) "A" "B"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接