While working in Scala, everyone comes across implicit but only a few try to understand how it actually works. So if you are wondering how implicit in scala works, then this blog will help you to understand it. So let’s talk about implicit.
What are implicits?
When we talk about implicits, we mean implicit parameters or conversions that happen implicitly. Both of these involve the compiler implicitly (i.e. invisibly) resolving certain type errors using extra information supplied in scope but not at the site of the type error. For implicit parameters, this is the error that occurs when a method call does not supply all the required parameters. For implicit conversions, it’s the error that occurs when a supplied type does not match the expected type.
Let’s talk about Implicit Parameters first
Implicit parameters are the ones that come along with a keyword,
implicit, and we don’t have to explicitly pass an argument for these parameters if they were in Scope. For example, changing an integer variable to a string variable can be done by a Scala compiler rather than calling it explicitly.
val message = "Hello " implicit val name = "Bhavya" def display(implicit str : String) = message + str // Implicit parameter will be passed here val result = display // Implicit parameters will not be passed val result2 = display("Bhavya Verma") println("With Implicit parameters:") println(result) println("Without Implicit parameters:") println(result2) Output: With Implicit parameters: Hello Bhavya Without Implicit parameters: Hello Bhavya Verma
In the above example, display method takes implicit parameter. So, if no parameter is passed while calling display method like in case of val result, scala compiler will look for any implicit in the scope and will automatically pass it to the method and if a parameter is passed explicitly like in case of val result2, then the implicit will not be used since the passing of parameter explicitly has a higher precedence.
What happens if we use 2 implicits in the same scope? Let’s see that through an example similar to the above example.
val message = "Hello " implicit val name = "Bhavya" implicit val fullName = "Bhavya Verma" def display(implicit str : String) = message + str val result = display println(result)
If we compile the above code, then we will get the following error
ambiguous implicit values: both value fullName of type String and value name of type String match expected type String val result = display
So this shows that we are not allowed to use more than 1 implicit value in the same scope.
Besides supplying missing parameters, the other thing the Scala compiler can do implicitly is transform one type into another. It will look for opportunities to do this whenever there is a type mismatch, i.e. when the compiler expects an expression to be of one type but it is actually of a different type.
Let’s now understand implicit conversion through an example.
val number: Int = 4.5
Here we can see that the variable number has a type Int but the value assigned to it is 4.5 i.e a Double. So, it will give a type mismatch error. So how can we resolve it? What can be the alternative to make it right without actually providing it with an integer value? For that, we can do the following:
implicit def doubleToInt(double: Double): Int = double.toInt val number: Int = 4.5 println(number) Output: 4
In the above code, we are now able to assign value of type double to number which is of type Int because we have an implicit method doubleToInt which is converting the value of type double to the value of type Int. When we are going to assign the value of type double to number, scala compiler will look for any implicit in the scope that it can use to resolve the type mismatch problem. If the method doubleToInt does not have implicit keyword at the start, then the compiler will give type mismatch error.
We have on the one hand the ability of implicit parameters to magically supply missing arguments of a matching type. We have on the other hand the ability of implicit conversions to magically turn an object from one type into another in order to supply missing functionality.
I hope you understood the concept of implicits in scala.