Implicit parameters and conversions in Scala

Having run over the previous articles on Habr, tyts and tyts were not able to quickly understand what implicit does 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 implicitly for us:

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 look at two implicit categories, namely:

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

Implicit parameter


An 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 personally search for the implicit parameter and pass it for us.

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

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

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

def double(implicit value: Int) = value * 2
println(double) // error: could not find implicit value for parameter value

With an explicit parameter passed, it will work:

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

With an implicit parameter, it will 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 def as an implicit parameter:

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

Those. in the end we will succeed
double(cappucinoPrice())

Syntax Notes:


def func1(implicit value1: Int)                          // value1 неявно
def func2(implicit value1: Int, value2: Int)             // value1 и value2 неявны
def func3(value1: Int, implicit value2: Int)             // ошибка компиляции
def func4(value1: Int)(implicit value2: Int)             // только value2 неявно
def func5(implicit value1: Int)(value2: Int)             // ошибка компиляции
def func6(implicit value1: Int)(implicit value2: Int)    // ошибка компиляции

Implicit conversion


Returning to the example from Float to Int:

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

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

Now, I hope, it has become clearer. All success in mastering Scala!

Also popular now: