Scala中的VarArgs函数和@varargs批注

时间:2020-02-23 14:46:20  来源:igfitidea点击:

在本文中,我们将讨论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程序中使用此方法。