Reminders
The companion object (both for own code and Scala’s API)
// The class definition with primary constructor class A protected (val arg1: String, private arg2: String) { // imports definitions from companion object import A._ // attributes and primary constructor code var busy = false // methods override def toString() = "A" } // Companion object comes after class/trait definition object A { // utility constructors apply(arg: String): A = new A("a", arg) // apply and unapply methods for object pattern matching (like case classes) // static methods } val a = A("test")
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 // private variable to hold value def value(): Int = v def value_= (t: Int) { 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 } } } Email("me@host.com") match { case Some(name,host) => println("Username is " + name) case None => 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)
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
- Artima.com: Programming in Scala - by Martin Odersky, Lex Spoon, and Bill Venner
- Scala-lang.org: A Tour of Scala - Online book with short descriptive examples
- Scala-lang.org: Scala By Example (pdf)