我听说 Scala 包含一个名为命名参数和默认参数的功能,但我不知道这些参数的作用或如何使用它们。
有人可以解释他们的用法吗?
Scala中的一些特殊函数调用类型
命名参数:
命名参数允许您以不同的顺序将参数传递给函数。例如:
def speed(distance: Float, time: Float): Float = distance / time
它可以像这样使用:
speed(distance = 100, time = 10)
或者
speed(time = 10, distance = 100)
默认参数:
Scala 允许您指定函数参数的默认值。例如:
def printTime(out: java.io.PrintStream = Console.out) =
out.println("time = "+ System.currentTimeMillis())
然后您可以调用 printTime 而不提供任何输出流,如下所示:
printTime()
反复论证:
Scala 允许您指示函数的最后一个参数可能是重复的。例如:
def echo(args: String*) =
for (arg <- args)
println(arg)
然后你可以像这样使用它:
echo()
echo("one")
echo("hello", "world!")
默认参数解决了其他编程语言通常通过方法重载解决的问题。当有方法时
def addNumbers(a: Int, b: Int, c: Int, d: Int) = a+b+c+d
它需要多个参数,如果不想填充所有参数,在重载方法中设置一些默认值以提供一种更易于使用的 API 会很有用:
def addNumbers(a: Int, b: Int, c: Int) = addNumbers(a, b, c, 0)
def addNumbers(a: Int, b: Int) = addNumbers(a, b, 0, 0)
使用默认参数不再需要重载这样的方法:
def addNumbers(a: Int, b: Int, c: Int = 0, d: Int = 0) = a+b+c+d
如果未指定,编译器会自动使用特定的默认参数调用该方法:
scala> addNumbers(1, 2, 3)
res2: Int = 6
默认参数的一个有用的地方是在构造函数中。写起来更容易
class A(i: Int, s: String = "")
比
class A(i: Int, s: String) {
def this(i: Int) = this(i, "")
}
另一方面,命名参数可以提高方法调用的可读性:
def compute(xs: List[Int], executeInParallel: Boolean) = ???
compute(xs, executeInParallel = true)
比只更容易阅读compute(xs, true)
无论其顺序如何,始终可以指定参数的名称。这意味着compute(executeInParallel = true, xs = xs)
与 相同compute(xs, true)
。当参数的顺序发生变化时,编译器通常只需要提示哪些参数必须放在哪个位置。
可以使用命名参数和默认参数的用例在于案例类的复制方法,它由编译器自动生成:
scala> case class Person(name: String, age: Int)
defined class Person
scala> val p = Person("Ruben", 43)
p: Person = Person(Ruben,43)
scala> val oneYearOlder = p.copy(age = p.age+1)
oneYearOlder: Person = Person(Ruben,44)
值得一提的是,命名参数仅适用于 Scala 中定义的方法。Java 中定义的方法的参数不能通过它们的名称来调用。
此外,命名参数不适用于函数文字:
scala> val f = (i: Int) => i
f: Int => Int = <function1>
scala> f(i = 1)
<console>:9: error: not found: value i
f(i = 1)
^
有关此功能的更多信息,可以查看docs.scala-lang.org。