Reminders on Scala syntax

Reminders

The companion object (both for own code and Scala’s API)

// The class definition with primary constructor
class Node protected (val a: String, private var b: String) {
  // imports definitions in companion object
  import Node._ 
 
  // attributes and primary constructor code
  var busy = false
 
  // methods
  override def toString() = "A"
}
 
// Companion object comes after the class/trait definition
object Node {
  // apply and unapply methods for object pattern matching (like case classes)
  // and object construction
  apply(arg: String): A = new A("a", arg)
 
  // static methods and variables
}
 
val node = Node("test","me")

Setter and getter functions are defined implicitly for val, var and referenced arguments in primary constructor. To set these manually

class A {
  private[this] var v: Int = 0 // avoids implicit setters and getters
  def value(): Int = v
  def value_=(t: Int): Unit = { v = t } // setters returns Unit
}

Adding indexing operators

// Here T give the type parameter for the class
class A[T] (size: Int) {
  private val array = new Array[T](size)
  def apply(index: Int): T = { /** get index value */ }
  def update(index: Int, value: T): Unit = { /** set index value*/ }
}
 
val a = new A[Int](100)
a(0) = 1
val n = a(0)

Binding a variable during pattern matching

str match {
  case bound @ "A match!" => println(bound)
  case _ => // no match
}

Defining an extractor for pattern matching (example lacks validation)

object Email {
  def apply(user: String, domain: String): String =
    user + "@" + domain
 
  def unapply(str: String): Option[(String,String)] = {
    str.split("@").toList match {
      case user :: domain :: Nil => Some(user,domain)
      case _ => None
    }
  }
}
 
"me@host.com" match {
  case Email(name,host) => println("Username is " + name)
  case _ => println("Invalid email address")
}

Imports can be grouped

import scala.collection.mutable.{Map,Stack,Queue}

Types can be aliased

type QMap = Map[Int,Queue[Int]]

Upper A <: T (A is a subtype of T) and lower A >: T (A is a supertype of T) bounded type parameters

class List[+A](elem: A, next: Option[List[A]]) {
  def prepend[B >: A](newElem: B): List[B] = new List(newElem, Some(this))
}
// scala> val l1 = new List(1.0, None)
// l1: List[Double] = List@1f49969
// scala> val l2 = new List(10,Some(l1))
// l2: List[AnyVal] = List@19bf996
 
def sort[T <: Ordered[T]](list: List[T]) { /** ... */ }

Writing () is optional with no arguments, and . is optional for methods with one argument

val b = new B
List(1,2,3) map (_ * 2)

The return keyword is optional (and curly braces on a single expression too)

def test() = "test"

The return type Unit is implicit when functions are declared without =

def printBig(str: String): Unit = {
  println(str.toUpperCase)
  () /** explicitly end the expression with the unit value */
}
def printBig(str: String) { println(str.toUpperCase) } /** same as previous */

References

Leave a Reply

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