【问题标题】:How can I pick one of a set of overloaded functions in Scala如何在 Scala 中选择一组重载函数中的一个
【发布时间】:2013-06-14 19:22:11
【问题描述】:

如何引用一个函数的重载?这需要反思吗?

----- Define two functions with the same signature

scala> def f( x:Int ) = x + 1
f: (x: Int)Int

scala> def g( x:Int ) = x + 2
g: (x: Int)Int

----- Define a function that returns one or the other

scala> def pick( a:Boolean ) = if (a) f _ else g _
pick: (a: Boolean)Int => Int

scala> pick(true)(0)
res24: Int = 1

scala> pick(false)(0)
res25: Int = 2

----- All good so far; now overload f to also take a String

scala> def f( x:String ) = x.toInt + 1
f: (x: String)Int

scala> def pick( a:Boolean ) = if (a) f _ else g _
pick: (a: Boolean)String with Int => Int

scala> pick(false)(0)
<console>:12: error: type mismatch;
 found   : Int(0)
 required: String with Int
              pick(false)(0)
                          ^

我明白为什么这不起作用。但是如何定义 pick 以使用采用 Int 的 f,而忽略采用 String 的 f?

同样,我不想编写调用 f 或 g 的函数。我想编写一个 返回 f 或 g 的函数,然后我可以调用无数次。

【问题讨论】:

    标签: scala overloading


    【解决方案1】:

    只需添加类型注释:

    def pick( a:Boolean ) = if (a) f(_: Int) else g(_: Int)
    

    【讨论】:

    • 太棒了——谢谢。请注意阅读本文的其他人,为了在 REPL 中看到这项工作,您必须使用粘贴模式(如 som-snytt 所示)。
    【解决方案2】:

    补充:不要被 REPL 如何构建它运行的东西所迷惑:

    scala> :pa
    // Entering paste mode (ctrl-D to finish)
    
    object Foo {
    def f(i: Int) = i.toString
    def f(s: String) = s
    def pick( a:Boolean ) = if (a) f _ else "nope"
    }
    
    // Exiting paste mode, now interpreting.
    
    <console>:10: error: ambiguous reference to overloaded definition,
    both method f in object Foo of type (s: String)String
    and  method f in object Foo of type (i: Int)String
    match expected type ?
           def pick( a:Boolean ) = if (a) f _ else "nope"
                                          ^
    

    使用 REPL,您问题的另一个答案是,定义您最后想要的那个,因为它变得最具体:

    scala> def f(s: String) = s
    f: (s: String)String
    
    scala> def f(i: Int) = i.toString
    f: (i: Int)String
    
    scala> f _
    res0: Int => String = <function1>
    

    【讨论】:

    • 很高兴知道!不幸的是,在我的情况下,有问题的方法是 Spray 人路由 DSL 的一部分,所以我无法控制他们的顺序......
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 2021-06-27
    相关资源
    最近更新 更多