[From the sandbox] Implicit parameters and conversions in Scala

[From the sandbox] Implicit parameters and conversions in Scala


Running through previous articles on Habré, tyc and tyts never managed to figure out in a quick way what makes implicit in Scala. Let's try to figure it out together.


So, implicit in Scala allows you to avoid calling methods or explicit references to variables, and instead allow the compiler to find the necessary implicit data itself.

For example, we could write a function to convert from Float to Int (FloatToInt) and, instead of calling this function explicitly, the compiler would do it instead of us implicitly:

  def double (value: Int) = value * 2
 implicit def FloatToInt (value: Float): Int = value.toInt
 println (double (2.5F))
  

Confused? Let's get everything in order.

So today we will look at two implicit categories, namely:

  • Implicit parameters (implicit parameters, values). They are automatically compiled values ​​declared by implicit.
  • Implicit conversion (implicit conversion). If the type of the expected parameter does not match the input parameter, the compiler searches for any method in scope that is marked implicit and with the expected parameter and input parameter needed in this situation and automatically passes it.

Implicit Parameter


Implicit Parameter is a function parameter preceded by the implicit keyword. It means that if no value is passed when the function is called, the compiler will look for the implicit parameter in its own hand and pass it for us.

For example, such a function that takes an implicit value parameter as input and doubles it:

  def double (implicit value: Int) = value * 2
  

Without an implicit parameter, it will fall with an error:

  def double (implicit value: Int) = value * 2
 println (double)//error: couldn’t find a value for parameter value  

The explicitly passed parameter will work:

  def double (implicit value: Int) = value * 2
 println (double (3))//6  

With an implicit parameter, it would look like this:

  def double (implicit value: Int) = value * 2
 implicit val multiplier = 2
 println (double)//4  

But you need to be careful:

  def double (implicit value: Int) = value * 2
 implicit val multiplier = 2
 implicit val multiplier2 = 1
 println (double)//error: ambiguous implicit values ​​ 

And finally, an example with passing as an implicit parameter def:

  def double (implicit value: Int) = value * 2
 val cappucinoLarge: Boolean = false
 implicit def cappucinoPrice: Int = if (cappucinoLarge) 200 else 100
 println (double)//200  

Those. we end up with
  double (cappucinoPrice ())  

Syntax notes:

 
 def func1 (implicit value1: Int)//value1 implicitly
 def func2 (implicit value1: Int, value2: Int)//value1 and value2 are implicit
 def func3 (value1: Int, implicit value2: Int)//compilation error
 def func4 (value1: Int) (implicit value2: Int)//only value2 implicitly
 def func5 (implicit value1: Int) (value2: Int)//compilation error
 def func6 (implicit value1: Int) (implicit value2: Int)//compilation error
  

Implicit conversion


Returning to the Float example in Int:

  def double (value: Int) = value * 2
 implicit def FloatToInt (value: Float): Int = value.toInt
 println (double (2.5F))
  

When we call double, we have a mismatch of the type of the expected parameter (Int) with the incoming parameter (Float). Therefore, the compiler is looking for any method in scope that is marked implicit and with the expected parameter (Int) and input parameter (Float) that are needed in this situation. Finds FloatToInt, performs the conversion, and passes on the desired value to double.

Now, I hope, it has become clearer. All success in the development of Scala!

Source text: [From the sandbox] Implicit parameters and conversions in Scala