Implicit conversions and implicit parameters are Scala’s power tools that do useful work behind the scenes. With implicits, you can provide elegant libraries that hide tedious details from library users.
An implicit conversion from type S to type T is defined by an implicit value which has function type S => T, or by an implicit method convertible to a value of that type. Implicit conversions are applied in two situations:
- If an expression e is of type S, and S does not conform to the expression’s expected type T.
- In a selection e.m with e of type T, if the selector m does not denote a member of T.
Rather than create a separate library of String utility methods, like a StringUtilities class, you want to add your own behavior(s) to the String class, so you can write code like this:
Instead of this:
Then we can enrich the String class with an implicit method as follows:
When you call
increment on a String, which does not has that method at all. Thus, the compiler find the compatible one
StringImprovements and convert the string to StringImprovements via the implicit method
stringToString, this is the scenario-2 mentioned above.
Scala 2.10 introduced a new feature called implicit classes. An implicit class is a class marked with the implicit keyword. This keyword makes the class’ primary constructor available for implicit conversions when the class is in scope. This is similar to
monkey patching in Ruby, and
Meta-Programming in Groovy.
In real-world code, this is just slightly more complicated. According to SIP-13, Implicit Classes
An implicit class must be defined in a scope where method definitions are allowed (not at the top level).
This means that your implicit class must be defined inside a class, object, or package object. You can also check some other restrictions of implicit class here: http://docs.scala-lang.org/overviews/core/implicit-classes.html
A method with implicit parameters can be applied to arguments just like a normal method. In this case the implicit label has no effect. However, if such a method misses arguments for its implicit parameters, such arguments will be automatically provided.
The actual arguments that are eligible to be passed to an implicit parameter fall into two categories:
- First, eligible are all identifiers x that can be accessed at the point of the method call without a prefix and that denote an implicit definition or an implicit parameter.
- Second, eligible are also all members of companion modules of the implicit parameter’s type that are labeled implicit.
Implicits can be used to declare a value to be provided as a default as long as an implicit value is set with in the scope.
What’s the advantage this solution takes over the simple default value in parameter definition? The search of implicit value can be taken in the scope of
companion object, and thus you can keep the default value
private from the caller.
An implicit function parameter is also usable as an implicit conversion, and it’s more flexible than the traditional solution. Check the following codes:
order is a function with a single parameter, is tagged implicit, and has a name that is a single identifier. Therefore, it is an implicit conversion, in addition to being an implicit parameter. So, we can omit the call to order in the body of the function