如何引用采用varargs的函数

时间:2019-07-08 10:54:15

标签: scala variadic-functions

如果我定义以下函数以返回一个函数:

    def foo(): (Int*) => String = { is =>
        is.map(_.toString).mkString(", ")
    }

然后尝试引用它:

    val bar = foo()
    bar(1, 2, 3)

我收到编译器错误

Too many arguments (3) for method apply...

但是当我显式定义引用类型时,它可以很好地编译:

    val bar2: (Int*) => String = foo()
    bar2(4, 5, 6)

有什么方法可以定义函数foo()而不需要此显式引用类型吗?

1 个答案:

答案 0 :(得分:10)

这是known bug,是"fixed" in Scala 2.13,因为它完全取消了在方法签名之外的类型中使用*的功能。

如果您只关心2.13之前的Scala版本,则可以使用已确定的解决方法-用星号显式注释函数变量。如果需要支持2.13,则可以使用Scala的单一抽象方法语法来完成以下操作:

trait MyVarargsFunc[-A, +B] {
  def apply(is: A*): B
}

val f: MyVarargsFunc[Int, String] = is => is.map(_.toString).mkString(", ")

或者,如果您想真正喜欢:

trait *=>[-A, +B] { def apply(is: A*): B }

val f: Int *=> String = is => is.map(_.toString).mkString(", ")

然后:

scala> f(1, 2, 3)
res0: String = 1, 2, 3

这也可以在2.12(我检查过)上使用,并且应该在-Xexperimental上可以在2.11上使用(如果您显式实例化MyVarargsFunc,它甚至可以在2.10或vanilla 2.11上使用-您只需没有得到很好的函数文字语法)。