Scala/Import
Importation in Scala is a mechanism that enables more direct reference of different entities such as packages, classes, objects, instances, fields and methods. The concept of importing the code is more flexible in scala than Java or C++.
- The import statements can be anywhere. It could be at the start of class, with in a class or object or with in method or block.
- Members can be renamed or hidden while importing.
- Packages, Classes or objects can be imported into the current scope.
Import
editAny importation is defined using the keyword "import". A simple example of importing an object contained in a package:
package p1 {
class A
}
object B {
val x = new p1.A
import p1.A
val y = new A
}
In lines 1-3, a package named "p1" containing a class named "A" is declared. In lines 4-8, an object named "B" is defined. At line 5, a value named "x" is assigned a new instance of class "A" using the full identifier "p1.A" for class "A". At line 6, the keyword "import" is used, followed by the identifier "p1.A". The "import" declaration makes it possible for all following entities in the scope to refer directly to the last part of the identifier in the declaration, here the class "A". In the seventh line, the class "A" is referred to directly without having to use its full identifier.
Entities that can be imported includes members such as fields and methods of objects:
import math.Pi
import math.round
println("Pi is: " + Pi) //Prints "Pi is: 3.141592653589793".
println("Pi rounded is: " + round(Pi)) //Prints "Pi rounded is: 3".
In the first line, the field named "Pi" of object "math" is imported, making it available to entities following the import declaration. In the second line, the method named "round" of object "math" is likewise imported. In the fourth and fifth line, "Pi" and "round" is referred to directly without the normal required identifiers "math.Pi" and "math.round".
The members of instances can also be imported:
class Cube(val a:Double)
def volume(cube:Cube) = {
import cube.a
a*a*a
}
val cube1 = new Cube(4)
println("The volume of cube1 is: " + volume(cube1)) //Prints "The volume of cube1 is: 64.0".
In the first line a class named "Cube" with a value named "a" indicating side-length is declared. In lines 2-5, a method calculating a cube's volume is defined. At line 3, the field "a" of the argument named "cube" is imported, and in line 4 "a" is referred to directly. A new cube is instantiated in line 6, and its volume is printed in line 7.
Packages can also be imported:
package p1.p2 {
class A
}
import p1.p2
val a = new p2.A
In the first 3 lines, two nested packages named "p1" and "p2" are declared, with "p2" containing a class named "A". At the fifth line, "p2" is imported. At the seventh line, "p2" is referred to directly without having to qualify it with "p1.p2".
You can import multiple classes from a package in the following way.
import math.{Pi,round}
math.Pi and math.round classes are imported from the math package in the single import statement.
Wildcard
editThe _ character is used as the wild character in Scala. It is similar to the * character in Java. In the below example everything is imported from the math package.
import math._
println("Pi is: " + Pi) //Prints "Pi is: 3.141592653589793".
println("Pi rounded is: " + round(Pi)) //Prints "Pi rounded is: 3".
Import selector clause
editRenaming
editTo avoid namespace collisions you may have to rename the members while importing into the scope. In the below example Pi is renamed as myPi and round as myRound while importing from the math package so that it doesn't collide with the local Pi and round members of the object.
import math.{Pi => myPi,round => myRound}
object myMaths extends App {
val Pi = 3.1
val round = TRUE
println("Pi is: " + myPi) //Prints "Pi is: 3.141592653589793".
println("Pi rounded is: " + myRound(myPi)) //Prints "Pi rounded is: 3".
}
Hiding
editScala provides an option to hide one or more classes while importing other members from the same package.
import math.{Pi => _, _}
object myMaths extends App {
println("Pi is: " + Pi) // Error, Pi is hidden
}
In the above example Pi is hidden and every thing else from the math package is imported into the scope. Accessing Pi in the example would give as an error as the Pi is hidden while importing.
Limiting the scope
editYou can use an import statement anywhere and this allows to control the scope of the imported members.
You can use the import statement at the top of the package.
package importTesting
import math.Pi
class test1 {
def printPi {
println("Pi is: " + Pi) //Successful
}
}
class test2 {
def printMyPi {
println("Pi is :" + Pi) //Successful
}
}
In the above example math.pi is imported at the top of the package and scope of the math.pi is throughout the package. So it can be used in all the classes with in the package.
You can use import statement with in the class.
package importTesting
class test1 {
import math.Pi
def printPi {
println("Pi is: " + Pi) //Successful
}
}
class test2 {
def printMyPi {
println("Pi is :" + Pi) //Fail as the scope of Pi is limited to class test1
}
}
In the above example math.pi is imported within the class test1 and the scope of the Pi is limited within the class test1. and it can not be accessed from the class test2.
You can use the import statement within the method of class and limit the scope to that member.
package importTesting
class test1 {
def printPi {
import math.Pi
println("Pi is: " + Pi) //Successful
}
def printMyPi {
println("Pi is :" + Pi) //Fail as the scope of Pi is limited to the method
}
}