【问题标题】:Distinguishing between f# overloaded functions with optional parameters区分带有可选参数的 f# 重载函数
【发布时间】:2017-04-12 20:37:33
【问题描述】:

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

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

如何调用第一个函数?

【问题讨论】:

  • 你可以在任何函数中重命名第二个参数: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)

标签: f#


【解决方案1】:

如果两个重载函数仅在可选参数上有所不同,我认为调用第一个函数是不明智的。如 cmets 中所述,使用这可能是一个糟糕的设计,您应该重命名参数。

您可能已经注意到,当您尝试使用MyClass().func("A","B") 以普通方式调用该函数时,您会收到一条错误消息,抱怨存在歧义:

错误 FS0041:无法根据此程序点之前的类型信息确定方法“func”的唯一重载。可能需要类型注释。候选:成员 MyClass.func : a:string * ?b:string -> string,成员 MyClass.func : a:string * b:string -> string

您可以通过两种方式显式调用第二个重载(使用或不使用?b),这要归功于您可以为可选参数显式提供Some 值:

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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    相关资源
    最近更新 更多