Scala中的VarArgs函数和@varargs批注
在本文中,我们将讨论Scala中具有Var-Args(可变参数个数)概念的函数。
介绍
Var-Args函数(方法)表示采用可变数量的参数。
作为Java开发人员,我们已经尝试过在基于Java的应用程序中使用Var-Args方法。
与Java一样,Scala也支持对函数(方法)使用"可变数量的参数"。
Scala遵循Java的Var-Args方法等相同规则,但语法有所变化。
我们将在下一节中讨论这些细节。
和我一样,如果有人从Java迁移到Scala,最好比较一下Java语言和Scala语言的功能和语法,以轻松学习它们。
Java中带有VarArgs的方法
Java 5引入了Var-Args参数功能。
它使用以下语法:
Method-Return-Type Method-Name(Argument2-Type Argument2Name ...)
Java使用3点"…"表示法来声明Var-Args参数。
我们可以在Argument名称之前或者Argument名称之后使用这3个点符号。
Java示例:
public class MyVarArgsClass{ public static void main(String args...){ } }
其中我们使用Var-Args参数声明了标准的main()方法。
在内部,JVM将这些Var-Args参数仅转换为数组。
Scala中带有VarArgs的函数
Scala还遵循类似的语法来定义Var-Args参数。
但是它使用*定义Var-Args参数。
Scala的Var-Args函数语法:
def Method-Name(Argument1Name : Type, Argument2Name : Type*)
Scala示例:
def display(str: String*) { str.map(println) }
此处的" str"是要显示功能的Var-Args参数。
Scala的Var-Args函数规则
与Java一样,Scala的Var-Args函数在评估和解析Var-Args参数时遵循以下规则。
Var-Args参数是通过使用*(星号)定义的。
Var-Args参数必须是参数列表中的最后一个参数。
由于上述条件,每个Function(Method)都接受一个且仅一个Var-Args参数。
Var-Args参数不接受"默认参数值"。
Scala的Var-Args函数示例
在本节中,让我们通过一些简单的示例逐一探讨Var-Args规则。
示例1:-编写具有Var-Args函数的Scala程序。
object ScalaVarArgsExample{ def display(str: String*) { str.map(println) } }
Scala REPL输出:
scala> object ScalaVarArgsExample{ def display(str: String*) { str.map(println) } } defined module ScalaVarArgsExample scala> ScalaVarArgsExample.display("Play","Scala","Java"); Play Scala Java scala>
示例2:-编写一个Scala程序在函数中同时使用Non-VarArgs和Var-Args。
def display(name:String, str: String*) { println("Non-VarArgs : " + name) println("VarArgs : ") str.map(println) } def main(args: Array[String]) { display("Rams", "Scala", "Java", "Play") } }
如果您在REPL或者任何Scala IDE中执行此程序,我们将获得以下输出:
Non-VarArgs : Rams VarArgs : Scala Java Play
注意:-该程序的显示方法包含两种参数:第一个参数是Non-VarArgs,最后一个是VarArgs。
我们同时遵循(2)和(3)规则。
如果使用相反的顺序,或者使用多个Var-Args参数,则会出现编译错误。
Scala中的@varargs注释
在Scala中,我们可以使用@varargs注释来注释Var-Args方法,如下所示:
object ScalaVarArgsExample{ @varargs def display(str: String*) { str.map(println) } }
Scala中的@varargs注释是什么? @varargs批注在" scala.annotation"包中定义。
该注释用于标记Scala的VarArgs方法,如上所示。
这个@varargs注释在Scala程序中有什么用?如果有类似的需求,例如我们需要在Java程序中使用Scala的VarArgs方法,则应在该Scala的VarArgs方法上标注@varargs批注。
示例1:-编写一个Java程序来调用Scala的VarArgs方法。
Scala程序
import scala.annotation.varargs object ScalaVarArgsExample{ @varargs def display(str: String*) { str.map(println) } }
Java程序
public class JavaProgramToUseScalaVarArgs { public static void main(String args[]){ ScalaVarArgsAndNonVarArgsDemo.display("Rams", "Scala", "Java", "Play"); } }
运行此Java程序时,将获得以下输出(与scala示例相同的输出):
Non-VarArgs : Rams VarArgs : Scala Java Play
注意:-如果我们从Scala的方法定义中删除@varargs批注并运行Java程序,则将出现以下编译错误:
Error:(9, 38) java: method display in class com.theitroad.posts.ScalaVarArgsAndNonVarArgsDemo cannot be applied to given types; required: java.lang.String,scala.collection.Seq<java.lang.String> found: java.lang.String,java.lang.String,java.lang.String,java.lang.String reason: actual and formal argument lists differ in length
这意味着display的VarArgs参数的类型不是" java.lang.String",而是" scala.collection.Seq"类型。
当我们用@varargs注释注释Scala的方法时,Scala会将这种" Seq"类型转换为" java.lang.String"类型。
当我们使用@varargs注释对Scala的VarArgs方法进行注释时,幕后情况会怎样?默认情况下,Scala的VarArgs参数类型为" scala.collection.Seq [T]"。
在我们的display()方法中,因为我们使用的是String VarArgs参数,所以其类型为" scala.collection.Seq [String]"。
当我们用@varargs注释注释该显示方法时,Scala会自动将" scala.collection.Seq [String]"类型转换为" java.lang.String []"类型。
这样我们就可以在Java程序中使用此方法。