如何引用带有可变参数的函数

How to reference a function that takes varargs

如果我将以下函数定义为return一个函数:

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() 而不需要这个显式引用类型?

这是一个 known bug, which was "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—你只是没有得到很好的函数文字语法)。