是否可以在Scala方法函数定义中组合变量参数和默认参数?具体来说,我正在尝试编写具有以下签名的补丁方法:
def patch(body: String, contentType: ContentType = ContentType.APPLICATION_JSON, customHeaders: (String, String)*)
我收到错误Parameter section with *-parameter cannot have default arguments
。因此,我认为这是对参数进行排序的问题。但是,我必须最后放置*参数。
我的问题是:
为什么*参数必须是最后一个?这样编译器可以轻松解析参数吗?
为什么*参数不能在默认参数之后出现?我想在适用于编译器更容易解析参数的地方使用相同的参数,因为默认参数和变量参数都是可选的。
答案 0 :(得分:3)
为什么*参数必须是最后一个?
从技术上讲,即使*参数不限于最后一个,编译器也应该能够弄清楚。 SO link为可能的原理提供了一些见解(尽管是非正式的)。
为什么*参数不能在默认参数之后出现?
如果在默认参数后允许* -parameter,则在某些情况下应该为参数变量分配所提供的参数存在歧义。例如:
def foo(a: String = "hi", bs: String*) = a + " " + bs.mkString(" ")
foo("hello", "world") // Should "hello" go to `a` or be a part of `bs`?
请注意,从技术上讲,也可以通过在出现歧义的情况下(例如foo(a="hello", "world")
要求显式的变量变量赋值)来解除此限制。
要规避该限制,您可以求助于curring(这使您可以在每个参数列表中使用*参数):
def bar(s: String, i: Int = 1, ts: (String, String)*) =
ts.map(t => (t._1 + s*i, t._1 + s*i))
// <console>:23: error: a parameter section with a `*'-parameter is not allowed to have default arguments
// def bar(s: String, i: Int = 1, ts: (String, String)*) = {
def bar(s: String, i: Int = 1)(ts: (String, String)*) =
ts.map(t => (t._1 + s*i, t._2 + s*i))
bar("!", 2)(("a", "b"), ("c", "d"))
// res1: Seq[(String, String)] = ArrayBuffer((a!!,b!!), (c!!,d!!))