VarArgs Functions and @varargs Annotation in Scala

Filed Under: Scala

In this post, we are going to discuss about Functions with Var-Args (Variable Number Of Arguments) concept in Scala.

Introduction

Var-Args Functions(Methods) means taking Variable Number of Arguments. As a Java Developer, We have already tasted usage of Var-Args methods in Java-based Applications.

Like Java, Scala also supports “Variable Number Of Arguments” to Functions(Methods). Scala follows same rules like Java’s Var-Args Methods with some syntax changes. We will discuss these details in next section.

Like myself, if someone is moving from Java to Scala, it is always better to compare both Java and Scala Languages features and syntax to learn them easily.

Methods With VarArgs in Java

Java 5 has introduced Var-Args Parameters feature. It uses the following syntax:


  Method-Return-Type Method-Name(Argument2-Type Argument2Name ...)

Java uses 3 dots “…” notation to declare the Var-Args parameters. We can use this 3 dots notation either before Argument name or after Argument name.

Java Example:-


  public class MyVarArgsClass{
      public static void main(String args...){ }
  }

Here we have declared standard main() method by using Var-Args parameter. Internally, JVM converts these Var-Args parameter to array only.

Functions With VarArgs in Scala

Scala also follows similar kind of syntax to define Var-Args parameter. But it uses * to define Var-Args parameter.

Scala’s Var-Args Functions Syntax:-


  def Method-Name(Argument1Name : Type, Argument2Name : Type*)

Scala Example:-


  def display(str: String*) {
    str.map(println)
  }

Here “str” is a Var-Args parameter to display function.

Scala’s Var-Args Functions Rules

Like Java, Scala’s Var-Args Functions follows these Rules in evaluating and resolving Var-Args Parameters.

  • The Var-Args Parameter is defined by using * (Star symbol).
  • The Var-Args Parameter must be the last parameter in the Parameter List.
  • Because of the above condition, each Function(Method) accepts one and only one Var-Args Parameter.
  • The Var-Args Parameter does not accept “Default Parameter Values”.

Scala’s Var-Args Functions Examples

In this section, let us explore Var-Args rules one by one with some simple examples.

Example-1:-
Write a Scala program with a Var-Args Function.


object ScalaVarArgsExample{
 
  def display(str: String*) {
    str.map(println)
  }
  
}

Scala REPL output:-


scala> object ScalaVarArgsExample{

  def display(str: String*) {
    str.map(println)
  }

}
defined module ScalaVarArgsExample

scala> ScalaVarArgsExample.display("Play","Scala","Java");
Play
Scala
Java

scala>

Example-2:-
Write a Scala program to use both Non-VarArgs and Var-Args in a Function.


  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")
  }
}

If you execute this program in REPL or any Scala IDE, we will get the following output:


Non-VarArgs : Rams
VarArgs : 
Scala
Java
Play

NOTE:-
This program’s display method contains both kind of arguments: first argument is Non-VarArgs and last is VarArgs. We have followed both (2) and (3) rules.

If we use in reverse order or if we use more than one Var-Args argument, then we will get compilation error.

The @varargs Annotation in Scala

In Scala, we can annotate a Var-Args method with @varargs annotation as shown below:


object ScalaVarArgsExample{
 
  @varargs def display(str: String*) {
    str.map(println)
  }
  
}

What is @varargs annotation in Scala?
@varargs annotation is defined in “scala.annotation” package. This annotation is used to mark a Scala’s VarArgs method as shown above.

What is the use of this @varargs annotation in a Scala program?
If we have a requirement like we need to use a Scala’s VarArgs method in a Java Program, then we should mark that Scala’s VarArgs method with @varargs annotation.

Example-1:-
Write a Java Program to make a call to Scala’s VarArgs method.

Scala Program


import scala.annotation.varargs

object ScalaVarArgsExample{
 
  @varargs def display(str: String*) {
    str.map(println)
  }
  
}

Java Program


public class JavaProgramToUseScalaVarArgs {

    public static void main(String args[]){
        ScalaVarArgsAndNonVarArgsDemo.display("Rams", "Scala", "Java", "Play");
    }

}

When we run this Java Program, we will get the following output (Same output like scala example):


Non-VarArgs : Rams
VarArgs : 
Scala
Java
Play

NOTE:-
If we remove @varargs annotation from Scala’s method definition and run Java program, then we will get the following compilation error:


Error:(9, 38) java: method display in class com.journaldev.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

That means display’s VarArgs parameter’s type is not “java.lang.String”, it is referring “scala.collection.Seq” type. When we comment that Scala’s method with @varargs annotation, then Scala will convert this “Seq” type to “java.lang.String” type.

What will happen under-the-hood, when we annotate a Scala’s VarArgs method with @varargs annotation?
By default, Scala’s VarArgs Parameter type is “scala.collection.Seq[T]”. In our display() method, as we are using String VarArgs parameter, its type is “scala.collection.Seq[String]”.

When we annotate that display method with @varargs annotation, Scala will automatically convert that “scala.collection.Seq[String]” type to “java.lang.String[ ]” type. So that we can use this method from a Java Program.

That’s it all about Var-Args Parameters and @varargs Annotation in Scala. We will discuss some more Scala concepts in my coming posts.

Please drop me a comment if you like my post or have any issues/suggestions.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages