What are the hidden features of Scala that every Scala developer should be aware of?
One hidden feature per answer, please.
What are the hidden features of Scala that every Scala developer should be aware of?
One hidden feature per answer, please.
In scala 2.8 you can have tail-recursive methods by using the package scala.util.control.TailCalls (in fact it's trampolining).
An example:
Okay, I had to add one more. Every
Regex
object in Scala has an extractor (see answer from oxbox_lakes above) that gives you access to the match groups. So you can do something like:The second line looks confusing if you're not used to using pattern matching and extractors. Whenever you define a
val
orvar
, what comes after the keyword is not simply an identifier but rather a pattern. That's why this works:The right hand expression creates a
Tuple3[Int, Double, String]
which can match the pattern(a, b, c)
.Most of the time your patterns use extractors that are members of singleton objects. For example, if you write a pattern like
then you're implicitly calling the extractor
Some.unapply
.But you can also use class instances in patterns, and that is what's happening here. The val regex is an instance of
Regex
, and when you use it in a pattern, you're implicitly callingregex.unapplySeq
(unapply
versusunapplySeq
is beyond the scope of this answer), which extracts the match groups into aSeq[String]
, the elements of which are assigned in order to the variables year, month, and day.Excluding members from
import
statementsSuppose you want to use a
Logger
that contains aprintln
and aprinterr
method, but you only want to use the one for error messages, and keep the good oldPredef.println
for standard output. You could do this:but if
logger
also contains another twelve methods that you would like to import and use, it becomes inconvenient to list them. You could instead try:but this still "pollutes" the list of imported members. Enter the über-powerful wildcard:
and that will do just the right thing™.
Extending the language. I always wanted to do something like this in Java (couldn't). But in Scala I can have:
and then write:
and get
Scala 2.8 introduced default and named arguments, which made possible the addition of a new "copy" method that Scala adds to case classes. If you define this:
and you want to create a new Foo that's like an existing Foo, only with a different "n" value, then you can just say:
in scala 2.8 you can add @specialized to your generic classes/methods. This will create special versions of the class for primitive types (extending AnyVal) and save the cost of un-necessary boxing/unboxing :
class Foo[@specialized T]...
You can select a subset of AnyVals :
class Foo[@specialized(Int,Boolean) T]...