如果我定义以下函数以返回一个函数:
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()
而不需要此显式引用类型吗?
答案 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上使用-您只需没有得到很好的函数文字语法)。