Scala quick reference

This blog has been moved to new address: http://www.trongkhoanguyen.com.

Remembering many programming syntax is somehow painful for me. As I have not graduated yet, memorizing many programming languages for many courses at school really hurts me sometimes. Thus, It’s better for me to write here the scala code which can be used to solved regular tasks as I can quickly refer to.

1. Scala type hierarchy
scala class

 

Scala treats everything as objects.

Class Descrition
Any Every class inherits from a common super-class named Any.
AnyVal Base class of built-in value classes
AnyRef Base class of all reference classes (if being run on Java, AnyRef is an alias of java.lang.Object)For reference equality, AnyRef class has eq method, which cannot be overridden (behaves like == in Java for reference types). Opposite of eq is ne
ScalaObject Scala classes are different from Java classes in that they also inherit from a special marker trait called ScalaObject
Null The type of null reference, a subclass of every reference class
Nothing Subclass of every other class (including Null), don’t have value, useful for signaling abnormal termination

 2. Variable declaration with val & var
val immutableVar = value; // to declare an immutable variable (constant)
var mutableVar = value // to declare a mutable variable
If we don’t specify the keyword val or var, Scala will treat it as val.

Examples:

val x = 10; // x: Int = 10
x = 11; // Reassignment to val error
var y:Double = 30; // explicitly declare y:Double = 30.0
y = 15; // valid assignment

3. Function declaration
def funcName([parameters]) [: return_type] = {
//statements
}
Note: In Scala, if there is no return then the last expression is taken to be the return value. So, if the last expression is what you want to return, then you can omit the return keyword. Be careful with this.
Examples:

def maxFunction(x:Int, y:Int):Int={
  if(x>y) x else y
}
def noArgumentFunction()={
 println("No argument function was called")
}

4. Loop with for and foreach

def forLoop()={
  // foreach
  val arr:Array[Int] = Array(1, 2, 3)

  //Style 1
  arr.foreach(item => print(item))
  //Style 2 when only one argument is passed and only one statement to execute
  arr.foreach(print)
  
  // for
  //Style 3
  for(item <- arr)
    print(item)
  //Style 4
  for(i <- 0 to 2)
    print(arr(i))

  //Style 5
  for(i <- 0 until 3) // doesn't include the upper bound
    print(arr(i))
}

def whileLoop={
  var i:Int  = 0 // i must be mutable, otherwise error syntax
  while(i < 10){
    println(i)
    i += 1
  }
}

5. Array & collection
5.1. Array
Note: Array is always mutable (can change the elements of array)

val intarr = Array[Int](1,2,3)
val strArr = Array[String]("one", "two", "three")

5.2. List
Note:
– Scala List is always immutable
– Scala List does not offer append method, instead, use :+, but don’t use it due to low performance

val lst1 = List(1, 2,3)
val lst2 = List(4, 5,6)

//************************************************************
// Gets                                                      *
//************************************************************

assert(lst1.head == 1) // gets first element
assert(lst1.last == 3) // gets last element
assert(!lst1.isEmpty)
assert(lst1.size == 3)
assert(lst1.length == 3)

//****************************************************************
// Modifies the list (actually returns a new one, not modifies)  *
//****************************************************************

//Concats list
assert((lst1 ::: lst2).size == 6) // appends list. [1,2,3,4,5,6]
assert((lst1 :: lst2).size == 4) // appends list. [[1,2,3], 4, ,5 ,6]

assert(((1::lst1).size == 4)) // prepends item. [1,1,2,3]
//val res = lst1::1 // syntax error, because only integer has the :: method, not the list

assert((lst1 :+ 4).size == 4) // appends item. don't do this!

//Delete n elements in head
assert(lst1.drop(2).size == 1) // returns a new list with no 2 first elements in the original list

//************************************************************
// Some calculations                                         *
//************************************************************
assert(lst1.count(item => item > 2) == 1) // Counts
assert(lst1.filter(item => item <= 2).size == 2) // filters

assert(lst1.exists(item => item == 4) == false) // checks existence
assert(lst1.forall(item => item > 1) == false) // checks criteria
assert(lst1.sortWith((x, y) => x > y)(0) == 3)

5.3. Tuple
Note: Unlike list, tuple is also immutable but can hold multiple different types.
One good use of tuple is in returning multiple values from function call.

val pair = (1, "one")
assert(pair._1 == 1) // cannot access like pair(0)
assert(pair._2 == "one")

val tup:Tuple3[Int, String, String] = (1, "one", "un")
assert(tup._3 == "un")

def getName()={("A", "B")}
val (firstName, lastName) = getName()

5.4. Set & map
Note: scala set and map can be “immutable” or “mutable”, it depends on how you import & specify
set & map

var jetSet = Set("Vietnam airline", "VietJetair")
jetSet += "Jetstar"
jetSet += "Jetstar" // already exists => does not add
assert(jetSet.size == 3)

var dict = Map[Int, String]()
dict += (1->"one")
dict += (2->"two")

 6. Class & Object
Note: The notions of class and object in Scala are the same as other modern languages. However, in Scala, you can even declare a singleton object with syntax just as the same as declare a class, except changing the keyword class to object. The singleton object is the only one object in the program belonging to one specified class. You can think singleton object as a static class in C#.

“One difference between classes and singleton objects is that singleton objects cannot take parameters, whereas classes can. Because you can’t instantiate a singleton object with the new keyword, you have no way to pass parameters to it. Each singleton object is implemented as an instance of a synthetic class referenced from a static variable, so they have the same initialization semantics as Java statics. In particular, a singleton object is
initialized the first time some code accesses it. A singleton object that does not share the same name with a companion class is called a standalone object. You can use standalone objects for many purposes, including collecting related utility methods together, or defining an entry point to a Scala application.”
Scala does have keyword private & protected but doesn’t have public. Classes, fields, constructors and methods are public by default.
Any code placed in the class body (outside methods) will be placed in the primary constructor

// Class with constructor & private fields
class C(x: Int)// x is a private final integer
class C(private val x:Int) // same as previousvar c = new C(4)

// Class with constructor & public fields
class C(val x:Int)// x is a private final integer with public getter
var c = new C(4)
c.x

// Class with constructor & public fields
class C(var x:Int)// x is a private integer with public getter and setter
var c = new C(4)
c.x = 5

// Constructor is class body
class C(var x: Int) {
  assert(x > 0, "positive please")
  var y = x // public field
  val readonly = 5 // gettable but not settable field
  private var secret = 1 // private field
  def this = this(42) // alternative constructor
}

// if we define multiple constructors, in the first statement in these overloading constructors, we have to call the primary constructor or another overloading constructor.
abstract class D { ... } // declares abstract class
class C extends D { ... } // C inherits D

// multiple inheritance: use extends for the first and with for the rest.
// overriding requires the keyword override, and only the primary constructor can pass parameters to the base constructor.
trait T1; trait T2
class C extends T1 with T2
class C extends D with T1 with T2 // the order of mixins is significant. Traits further to the right take effect first

//Examples...
// Simple class
class SimpleGreeter {
  val greeting = "Hello, world!"
  def greet() = println(greeting)
}
val g = new SimpleGreeter
g.greet()

// Class with constructor
class RepeatGreeter(greeting: String, count: Int) {
  def this(greeting: String) = this(greeting, 1)
  def greet() = {
    for (i <- 1 to count)
      println(greeting)
  }
}
val g1 = new RepeatGreeter("Hello, world", 3)
g1.greet()
val g2 = new RepeatGreeter("Hi there!")
g2.greet()

//Static methods/class
// The WorldlyGreeter companion object
object WorldlyGreeter {
  def worldify(s: String) = s + ", world!"
}

// The WorldlyGreeter class
class WorldlyGreeter(greeting: String) {
  def greet() = {
    val worldlyGreeting = WorldlyGreeter.worldify(greeting)
    println(worldlyGreeting)
  }
}

6. Trait & mixins
Note: A Trait can be thought as an interface but can be provided implementations (same as AbstractClass)

trait Friendly {
  def greet(): String = {
    return "Hi"
  }
}

class Dog extends Friendly {
  override def greet() = "Woof"
}

trait ExclamatoryGreeter extends Friendly {
  override def greet() = super.greet() + "!"
}

Mix behaviour

val pup: Friendly = new Dog with ExclamatoryGreeter

Given the initial line of code, the Scala compiler will create a synthetic type that extends class Dog and trait ExclamatoryGreeter and instantiate it

trait Friendly {
  def greet() = "Hi"
}
class Dog extends Friendly {
  override def greet() = "Woof"
}
class HungryCat extends Friendly {
  override def greet() = "Meow"
}
class HungryDog extends Dog {
  override def greet() = "I'd like to eat my own dog food"
}
trait ExclamatoryGreeter extends Friendly {
  override def greet() = super.greet() + "!"
}
var pet: Friendly = new Dog
println(pet.greet()) // Woof
pet = new HungryCat
println(pet.greet()) // Meow
pet = new HungryDog
println(pet.greet()) // I'd like to eat my own dog food
pet = new Dog with ExclamatoryGreeter
println(pet.greet()) // Woof!
pet = new HungryCat with ExclamatoryGreeter
println(pet.greet()) // Meow!
pet = new HungryDog with ExclamatoryGreeter
println(pet.greet()) // I'd like to eat my own dog food!

7. Misc
7.1. Post-fix operator
Post-fix operators are methods that take no arguments, when they are invoked without a dot or parentheses. The convention is we include ‘(‘ & ‘)’ if the method has side effects and vice versa.

//Examples
"ABC" toLowerCase // same as "ABC".toLowerCase
List(1, 2, 3) reverse // same as List(1, 2, 3).reverse

Scala allows us to drop both the dot and the parentheses if a method takes either zero or one parameter (if more than one, we can still exclude the dot, but we’ll have to use parentheses).

7.2. Precondition
The require method takes one boolean parameter. If the passed value is
true, require will return normally. Otherwise, require will prevent the object
from being constructed by throwing an IllegalArgumentException

class Rational(n: Int, d: Int) {
  require(d != 0)
  override def toString = n +"/"+ d
}

 7.3. Switch case
– break is implicit and case expression can contain any type of value.
– ‘_’ is a placeholder for completely unknown value

val target = firstArg match {  // firstArg is a previously initialized val
  case "salt" => println("pepper")
  case "chips" => println("salsa")
  case "eggs" => println("bacon")
  case _ => println("waat?")
}

7.4 Trait vs abstract class

  • if it might be used in multiple, unrelated classes, use a trait
  • if you want to inherit from it in Java code, use an abstract class
    • a trait with only abstract members translates to Java interface
  • if you plan to distribute it in compiled form and you expect others to write classes that inherit from your code, use an abstract class (when a trait gains or loses a member, any class that inherit from it must be recompiled)
  • if efficiency is very, very important, use a class (in Java, a virtual method invocation of a class member is faster than an interface method invocation)
  • if none of the above fits your case, use trait

8. Language features

8.1. returning different value types in a function

def toInt(in: String): Option[Int] = {
 try {
 Some(Integer.parseInt(in.trim))
 } catch {
 case e: NumberFormatException => None
 }
}

toInt(someString) match {
 case Some(i) => println(i)
 case None => println("That didn't work.")
}

 

 

Advertisements
This entry was posted in Scala and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s