Value Assignment in Scala
Like many languages, the variable assignment in Scala is divided into two parts, a declaration and a value assignment separated by an assignment operator, which is an equal sign. Variables and basic types In Scala is much same as we found in Java and other languages.
The variable declaration starts with a keyword, followed by a space and then a variable name. It is then followed by a space and followed by a colon symbol, followed by the type you want to associate to the variable. For value, we provide either a literal value or by executing an expression or by calling a method which returns a value. Scala uses type inference to identify the type of the variable based on the values assigned.
With a var keyword, We can perform reassignments anytime, but with the val keyword , we can’t reassigned its values again, if i try to reassign the value of val then it throws an error, it says that doing a reassignment to a variable that is declared using a val keyword.
In Scala, the preference is to use val keyword at all times, unless there is a strong requirement to use a var keyword.
Fundamental Types in Scala
In Scala, everything is an object, and every object has a type. Lets see how fundamental types in Scala are organized. At the top we have a type called Any. This is the root of the type hierarchy. This means every object that we create inherits from Any. This is further classified into two subtypes, AnyVal, and AnyRef.
There are nine types of AnyVal represented in this diagram i.e. Byte, Short, Char, Int, Long, Float, Double, Boolean, and Unit. These are analogous to job of primitive types.
AnyRef refers to any object that inherits essentially from java.lang.object. This includes the string class, arrays, lists, or any class that you create in Scala. In Scala there is an elegant way to represent the idea of a value that could be absent at the compile time using Option.
Lets see the Scala’s types of AnyVal:
val anInt: Int = 5 // create an instance of type Integer val aDouble: Double = 3.2 // create an instance of type Double val aFloat: Float = 1.3f // create an instance of type Float val aLong: Long = 19999L // create an instance of type Long val aShort: Short = 12 // create an instance of type Short val aByte: Byte = 1 // create an instance of type Byte
These are all the instances of are categorised as numeric types because they store numeric values. There are few non-numeric types as well, such as Char, and few more.
val aChar: Char = 'c' // create an instance of type Char val aUnit: () = () // Unit type val aFalse: Boolean = false // create an instance of type Boolean
I create a variable of type Unit. The Unit type has one value, which is represented by an opening and closing parenthesis. The Unit type is mostly used in functions to represent the absence of return value.
If I try to assign a value to a Unit type, I get the warning because an expression always returns a value, which does not align with the Unit type. The last non-numeric type is a boolean with two values, false and true.
Let’s see an Scala’s examples of AnyRef type:
If we search for array in API documentation and look for its super types, we confirm that Array inherits from AnyRef, so lets create instance of Array
val arr: Array[Int] = Array(1,2)
I declare the Array of type Integer and initialize it with two numbers, 1 and 2. To initialize array, you call Array, then open a parenthesis, and provide the values separated by comma, and then close the parenthesis. Do remember that all the values in Array must be of same type.
We saw that Null is at the bottom of AnyRef, and lowercase “null” is the only instance value it can have.
val aNull: Null =null
I create a variable of type Null with lowercase “null” as the instance value and it seems to have worked. But if i assign a string literal to a null type, i get the error that the types do not match.
val aNull: Null = " a null" // type mismatch error we get
Nothing type is at the bottom of every type. The interesting information is that there exists no instance of this type. So how is this useful? One major benefit of a Nothing type is to use it as a return type when the computation does not happen normally, which means to signal failures.
In fact if we look at the scala.sys package, we would see this Nothing return type being used by methods such as exit and error.
Expression and Statements in Scala
An expression is something that yields a value.
x = 10 y = 20 x + y // Yields 30 as a result
For example, if we add two numbers, we get the result of the addition as part of the evaluation. So addition is an expression here.
Another example could be a function that takes a number and returns the square of the number as the result.
getSquareOf(number) // Yields the square of the given number
In this case function is an expression, since it yields a value.
On the other hand side, a statement is a line of code that does something. For example, printing the statement on the console prints the value, but it does not return anything.
print("Hello World") // Prints the text on the console
So statement is not an expression. Likewise , if you have a method or a function that does something, such as ordering a pizza function, which takes the order, is a statement here.
order(pizzas) // Submits an order
The key difference between an Expression and Statement is that while expressions do not contain side effects, statements may contain side effects in your code, such as writing to a file system, connecting to the network, among other things.
In functional programming, writing expressions are recommended since they yield a value. So it is easy to test them because they do not contain any side effects. In Scala, the last line of the block is the return value.