使用可变参数但使用命名参数调用函数的 Scala 语法是啥?

Posted

技术标签:

【中文标题】使用可变参数但使用命名参数调用函数的 Scala 语法是啥?【英文标题】:What is the Scala syntax for calling a function with variadic arguments but with named arguments?使用可变参数但使用命名参数调用函数的 Scala 语法是什么? 【发布时间】:2012-11-22 16:53:49 【问题描述】:

说我有一个函数

def f(a:Int = 0, b:String = "", c:Float=0.0, foos: Foo*)  ... 

注意某些参数使用默认参数。通常,要使用默认值,您可以调用带有命名参数的函数,如下所示:

val foo = Foo("Foo!")
f(foos = foo)

此语法有效,因为我只使用一个foo 调用该方法。但是,如果我有两个或更多

val foo1 = Foo("Foo!")
val foo2 = Foo("Bar!")
f(foos = ...)

这里应该输入什么并不那么明显。 Seq(foo1,foo2)Seq(foo1,foo2):_* 不进行类型检查。

还有,我怎么称呼它no foos?

// All out of foos!
f(foos = ...)

对于这种情况,使用空括号 (f()) 调用函数不起作用。

谢谢!

【问题讨论】:

你使用的是什么版本的scala?在 2.9.2 中尝试在 REPL 中定义 f 给了我一个“:9: error: a parameter section with a `*'-parameter is not allowed to have default arguments” 我也在 2.9.2 上看到了这个。但是,我正在编译的实际代码运行的是 2.9.1,这显然是合法的。 【参考方案1】:

对于默认参数,请参阅我对您的问题的评论。有关如何使用命名参数调用可变参数部分,请参见下文(scala 2.9.2):

scala> case class Foo(a:Int)
defined class Foo

scala> def f(a:Int, foos: Foo*) = foos.length
f: (a: Int, foos: Foo*)Int

scala> f(a=2, foos=Foo(2))
res0: Int = 1

// I'm not sure if this is cheating...
// am I just naming the first of the two variadic arguments?
scala> f(a=2, foos=Foo(2),Foo(3))
res1: Int = 2

//anyway you can do ....
scala> f(a=2, foos=Seq(Foo(1), Foo(2)):_*)
res2: Int = 2

// with no foos...
scala> f(a=2, foos=Nil:_*)
res3: Int = 0

【讨论】:

谢谢,这很清楚。我会接受你的回答,因为它更接近问题,但在实用性方面我认为我会采用 bluenote10 的方法。 @fatu 我知道我的回答是[技术上正确](www.deadprogrammer.com/technically-correct/)...我也认为 bluenote10 的方法更好,并且是更有用的正确品牌。你仍然可以不接受我并接受他的回答。【参考方案2】:

鉴于 Paolo 提到的 Scala 2.9 限制,您仍然可以使用 currying 将参数划分为不同的部分,一个使用带有默认参数的命名参数,一个用于可变参数(或者如果您想要多个 curry 参数部分,则可以使用多个可变参数)。关于可读性,结果几乎比仅使用命名参数更好:

f(b="something")()
f(c=3.14)(foo1, foo2)

【讨论】:

以上是关于使用可变参数但使用命名参数调用函数的 Scala 语法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Scala函数使用可变参数

Scala 可变长参数

如何使用 Scala 的 AnyVal 调用 Java 可变参数方法?

Kotlin:你可以为可变参数使用命名参数吗?

参数调用

Scala-变长参数