Как стать автором
Обновить

Неявные (implicit) параметры и преобразования в Scala

Время на прочтение2 мин
Количество просмотров5.4K
Пробежавшись по предыдущим статьям на Хабре, тыц и тыц так и не удалось в быстром режиме понять, что делает неявность (implicit) в Scala. Попробуем разобраться вместе.


Итак, implicit в Scala позволяют избежать вызывания методов или явных ссылок на переменные, и взамен этого позволяют компилятору самому найти нужные неявные данные.

Например, мы могли бы написать функцию для преобразования из Float в Int(FloatToInt) и, вместо того, чтобы вызвать эту функцию явно, компилятор бы сделал это вместо нас неявно:

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

Запутанно? Давайте обо всём по порядку.

Итак, сегодня мы рассмотрим две категории implicit, а именно:

  • Неявные параметры (implicit parameters, values). Они являются автоматически переданными компилятором значениями, объявленными через implicit.
  • Неявное преобразование (implicit conversion). При несовпадении типа ожидаемого параметра с входящим параметром компилятор ищет любой метод в области видимости, отмеченный implicit и с нужными в данной ситуации ожидаемым параметром и входящим параметром и автоматически его передаёт.

Неявный параметр


Неявный параметр — это параметр функции, которому предшествует ключевое слово implicit. Оно значит, что, если не передано никакого значения при вызове функции, то компилятор собственноручно будет искать неявный параметр и передаст его за нас.

Например, такая функция, принимающая на вход неявный параметр value и удваивающая его:

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

Без неявного параметра упадёт с ошибкой:

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

С переданным явно параметром сработает:

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

С неявным параметром это будет выглядеть так:

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

Но нужно быть аккуратным:

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

И напоследок пример с передачей в качестве неявного параметра def:

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

Т.е. в итоге у нас получится
double(cappucinoPrice())

Примечания по синтаксису:


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)    // ошибка компиляции

Неявное преобразование


Возвращаясь к примеру из Float в Int:

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

При вызове double у нас происходит несовпадение типа ожидаемого параметра (Int) с входящим параметром (Float). Поэтому компилятор ищет любой метод в области видимости, отмеченный implicit и с нужными в данной ситуации ожидаемым параметром (Int) и входящим параметром (Float). Находит FloatToInt, производит преобразование и передает дальше нужное значение в double.

Теперь, надеюсь, стало понятнее. Всем успехов в освоении Scala!
Теги:
Хабы:
Всего голосов 23: ↑19 и ↓4+15
Комментарии11

Публикации

Истории

Работа

Scala разработчик
10 вакансий

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань