如何引用采用varargs的函数

use*_*074 9 scala variadic-functions

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

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

然后尝试引用它:

val bar = foo()
bar(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

我收到编译器错误

适用于方法的参数(3)过多...

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

val bar2: (Int*) => String = foo()
bar2(4, 5, 6)
Run Code Online (Sandbox Code Playgroud)

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

Tra*_*own 10

这是一个已知的错误,该错误在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(", ")
Run Code Online (Sandbox Code Playgroud)

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

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

val f: Int *=> String = is => is.map(_.toString).mkString(", ")
Run Code Online (Sandbox Code Playgroud)

然后:

scala> f(1, 2, 3)
res0: String = 1, 2, 3
Run Code Online (Sandbox Code Playgroud)

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