Scala “implicits” allow you to omit calling methods or referencing variables directly but instead rely on the compiler to make the connections for you. For example, you could write a function to convert from and
Int to a
String and rather than call that function explicitly, you can ask the compiler to do it for you, implicitly.
In the next few posts, we’ll look at the different types of implicit bindings Scala offers and show some examples of when they can be useful.
There are three categories of “implicits”;
- Implicit parameters (aka implicit values) will be automatically passed values that have been marked as
- Implicit functions are
defs that will be called automatically if the code wouldn’t otherwise compile
- Implicit classes extend behaviour of existing classes you don’t otherwise control (akin to categories in Objective-C)
At it’s simplest, an implicit parameter is just a function parameter annotated with the
implicit keyword. It means that if no value is supplied when called, the compiler will look for an implicit value and pass it in for you.
You tell the compiler what it can pass in implicitly but annotating values with
and call the function like this
The compiler knows to convert this into a call to
multiply(multiplier). If you forget to define an implicit
var, you’ll get an error like the following.
error: could not find implicit value for parameter by: Int multiply ^
You can ask the compiler to call your function with an implicit
val (like we’ve just seen), a
var or even another
def. So, we could have written a function that returns an
Int and Scala would attempt to use that instead.
The compiler would try to resolve this as
However, you can’t have more than one in scope. So if we have both the
multipler value and
f function defined as implicit and call
multiply, we’d get the following error.
error: ambiguous implicit values: both value multiplier of type => Int and method f of type => Int match expected type Int multiply ^
You can only use
implicit once in a parameter list and all parameters following it will be implicit. For example;
As an example, the test below uses Web Driver (and specifically an instance of the
WebDriver class) to check that a button is visible on screen. The
beVisible method creates a
Matcher that will check this for us but rather than pass in the
driver instance explicitly, it uses an implicit
val to do so.
Implicit parameters are useful for removing boiler plate parameter passing and can make your code more readable. So if you find yourself passing the same value several times in quick succession, they can help hide the duplication.
The Scala library often use them to define default implementations that are “just available”. When you come to need a custom implementation, you can pass one in explicitly or use your own implicit value. A good example here is the
sorted method on
The really useful stuff though comes when we combine implicit parameters with the other types of “implicits”. Read more in the series to build up a picture.