如何引用一个接受可变参数的函数

10
如果我定义以下函数来返回一个函数:
def foo(): (Int*) => String = { is =>
    is.map(_.toString).mkString(", ")
}

然后尝试进行引用:

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

我遇到了编译器错误

方法apply的参数过多(3个)...

但是当我明确定义引用类型时,它可以编译通过:

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

有没有办法可以定义我的函数foo()而不需要这个显式的引用类型?


1
def foo(): (Int*) => String does not seem to compile on my machine with Scala 2.13. I get error: repeated parameters are only allowed in method signatures; use Seq instead - Mario Galic
1个回答

13

这是一个已知的错误,在Scala 2.13中通过彻底禁用类型中方法签名之外的*标识符来“修复”了该问题

如果只关心 Scala 2.13 之前的版本,您可以使用已经确认的解决方法 - 显式地注释带有星号类型的函数变量。如果您需要支持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(我已经检查过),并且在2.11上应该使用-Xexperimental,如果您显式实例化MyVarargsFunc,即使在2.10或纯2.11上也可以工作,只是您无法获得漂亮的函数字面语法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接