Let's Talk About Implicit
Let's Talk About Implicit
If you know Scala you must have heard about Implicit. I'll try to make it as easy as possible for you guys.
Join the DZone community and get the full member experience.Join For Free
What Is Implicit?
The literal meaning of implicit is "Something that is suggested or implied". We can see it as something that is not directly or that someone understands themselves. In Scala also, the implicit has pretty much similar meaning. Before going into much detail, I'll take a simple example and explain how the compiler implements it.
So here we can see that the variable number has a type Int but the value assigned to it is 3.5 i.e a Double. As expected, it shows a type mismatch problem. So how can we resolve it? What can be the alternative to making it right without actually providing it with an integer value? For that, we can do the following:
All this is happening because the function "doubleToInt" is Implicit. Scala compiler will look for any implicit in the scope that it can use to resolve the type mismatch problem that we have seen before. Here it finds the function "doubleToInt" and now the Scala compiler must insert the implicit function at the right place and use it for the conversion itself.
Rules for Implicit
Only definitions marked implicit are available.
This rule simply says that the compiler will only look at the functions, variables, or object definition that are marked as implicit.
It will help in avoiding the confusion for the compiler if it was picking the functions randomly.
An inserted implicit conversion must be in scope as a single identifier or be associated with the source or target type of the conversion.
This rule simply says that the implicit conversion should be in scope. In scope means that either it should be in the same class or object. If the conversion is in companion object then also it is good to go. Also, the implicit conversion can be associated with source type or target type. Now, what does the source type or target type mean?
Consider you are passing Rupee in a function that requires Dollar. In this Rupee is the source type and the Dollar is the target type. If we have an implicit conversion in source's or target's companion object then it is good to go. This is what we mean by associated here.
Only one implicit is inserted.
This rule simply says that the compiler will insert one implicit a time. Also, it won't insert another implicit if it is already in the middle of trying another implicit. And this makes sense. If the Scala compiler inserts and try all the implicit available at once it will increase compiler time.
Whenever code type checks as it is written, no implicit is attempted.
This says the compiler will not insert an implicit if the code already works. If we are doing a conversion explicitly or providing the parameter then the compiler won't look for an implicit. This saves compiler time. This also indicates that by doing things our self in the code and using less implicit will take less compiler time and also reduce the ambiguity.
A parameter in a class constructor or a function definition can be marked implicitly. By marking a parameter implicit we need not pass it explicitly. We just need to declare the implicit variable and the Scala compiler will insert it automatically. Let me show you this by an example.
The output will be:
Note: The above example is not a good use case. If there is more than one implicit variable of type String then it will show an error.
An implicit class has an implicit keyword with it. When we make a class implicit, the compiler generates an implicit function for it. This function takes the constructor variable as a parameter and creates an instance of the class.
By making a class implicit all its functions can be used by the constructor variable. Let me show you how.
Because we get this implicit method we can call the function isPalindrome by using a string. What happens is, the compiler gets a string but to use the isPalindrome function it needs an instance of Palindrome. So it searches for an implicit function that will convert string to Palindrome. Then it finds the automatically generated implicit function. And that's how all this is possible.
The advantage of making a class implicit is that we can make pre-defined types rich.
One thing to take care of is the implicit class can only have a single parameter and so it's not possible to make every class implicit.
The implicit functions are those that are marked implicit and are mainly used for the type conversion. The example that I have discussed above of the "doubletoInt" function or "rupeeToDollar" function is an example of an implicit function.
Disadvantage of Implicit
- Lot's of implicit can create ambiguity for the compiler.
- Many implicit can lead to more compiler time.
- Also sometimes if a person does not have good knowledge about how implicit work, he/she can face problems in debugging code.
That's all from my side. I hope it was helpful.
Published at DZone with permission of Muskan Gupta . See the original article here.
Opinions expressed by DZone contributors are their own.