Here are a collection of tips, tricks, and general information I have gleaned from using Scala for a while. These tips apply to Scala 2.7.3
Case classes
You can define a case class like so:
A case class definition, such as case class Foo(x: Int) does the following things:
The case keyword is merely a convenience; you can achieve the same result by writing this:
Don't confuse case classes and objects. If you define an object, and you want to instantiate it via ObjectName(), you must write an apply method in your object.
Pattern matching gotchas
A common mistake that newbies make is that Scala expects constants to be in uppercase. If you try to match a constant in uppercase, Scala will use that constant. If you try to match a constant that is in lowercase, Scala will think you want to bind a new variable to that identifier, resulting in unexpected behavior. Take a look at the following example:
// Binds a new variable to foo:
// Don't do this!
x match {
case foo => "yes"
case _ => "no" /* Unreachable code */
}
// Uses existing variable foo:
// Do this if you must.
x match {
case `foo` => "yes"
case _ => "no"
}
// Uses existing variable FOO:
// Do this because it's the best.
x match {
case FOO => "yes"
case _ => "no"
}
Synchronized collections (or adding other traits)
Multidimensional maps
case class MulMap[K1, K2, V] {
val wrapped = new scala.collection.mutable.HashMap[(K1, K2), V]
def update(k1: K1, k2: K2, v: V) = wrapped.put((k1, k2), v)
def apply(k1: K1, k2: K2) = wrapped((k1, k2))
}
val map = MulMap[String, String, Int]
map("apple", "orange") = 4
Multidimensional arrays
new Array[Array[Boolean]](width, height)
Case classes
You can define a case class like so:
A case class definition, such as case class Foo(x: Int) does the following things:
- Defines a class named Foo.
- Exposes a getter, x.
- Defines a case class constructor function, also named Foo.
The case keyword is merely a convenience; you can achieve the same result by writing this:
Don't confuse case classes and objects. If you define an object, and you want to instantiate it via ObjectName(), you must write an apply method in your object.
Pattern matching gotchas
A common mistake that newbies make is that Scala expects constants to be in uppercase. If you try to match a constant in uppercase, Scala will use that constant. If you try to match a constant that is in lowercase, Scala will think you want to bind a new variable to that identifier, resulting in unexpected behavior. Take a look at the following example:
// Binds a new variable to foo:
// Don't do this!
x match {
case foo => "yes"
case _ => "no" /* Unreachable code */
}
// Uses existing variable foo:
// Do this if you must.
x match {
case `foo` => "yes"
case _ => "no"
}
// Uses existing variable FOO:
// Do this because it's the best.
x match {
case FOO => "yes"
case _ => "no"
}
Synchronized collections (or adding other traits)
Multidimensional maps
case class MulMap[K1, K2, V] {
val wrapped = new scala.collection.mutable.HashMap[(K1, K2), V]
def update(k1: K1, k2: K2, v: V) = wrapped.put((k1, k2), v)
def apply(k1: K1, k2: K2) = wrapped((k1, k2))
}
val map = MulMap[String, String, Int]
map("apple", "orange") = 4
Multidimensional arrays
new Array[Array[Boolean]](width, height)
A shorter way to write list literals
def L[T](xs: T*) = List(xs: _*)
L(1, 2, 3)
// OR
val L = List
L(1, 2, 3)
// OR
import scala.{List=>L}
L(1, 2, 3)
Differences between val, lazy val and def
def L[T](xs: T*) = List(xs: _*)
L(1, 2, 3)
// OR
val L = List
L(1, 2, 3)
// OR
import scala.{List=>L}
L(1, 2, 3)
Differences between val, lazy val and def
- vals are only evaluated the first time they are declared.
- lazy vals are only evaluated the first time they are referenced.
- defs are evaluated each time they are referenced.
0 comments: on "Scala tips, tricks, and info"
Post a Comment