Parâmetros implícitos e conversões no Scala

Depois de passar por cima dos artigos anteriores sobre Habr, tyts e tyts não foram capazes de entender rapidamente o que implícito faz em Scala. Vamos tentar descobrir isso juntos.


Portanto, implícito no Scala permite evitar chamar métodos ou referências explícitas a variáveis ​​e permitir que o compilador encontre os dados implícitos necessários.

Por exemplo, poderíamos escrever uma função para converter de Float em Int (FloatToInt) e, em vez de chamar essa função explicitamente, o compilador faria isso implicitamente para nós:

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

Confuso? Vamos colocar tudo em ordem.

Hoje, olhamos para duas categorias implícitas, a saber:

  • Parâmetros implícitos (valores). Eles são transmitidos automaticamente pelos valores do compilador declarados via implícito.
  • Conversão implícita Se o tipo do parâmetro esperado não corresponder ao parâmetro de entrada, o compilador procurará por qualquer método no escopo marcado como implícito e com o parâmetro esperado e o parâmetro de entrada necessários nessa situação e o passará automaticamente.

Parâmetro implícito


Um parâmetro implícito é um parâmetro de função precedido pela palavra-chave implícita. Isso significa que, se nenhum valor for passado quando a função é chamada, o compilador pesquisará pessoalmente o parâmetro implícito e o passará para nós.

Por exemplo, uma função que pega um valor implícito de parâmetro como entrada e o dobra:

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

Sem um parâmetro implícito, ele falhará com um erro:

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

Com um parâmetro explícito passado, ele funcionará:

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

Com um parâmetro implícito, ele terá a seguinte aparência:

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

Mas você precisa ter cuidado:

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

E, finalmente, um exemplo com a passagem de def como um parâmetro implícito:

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

I.e. no final, teremos sucesso
 double(cappucinoPrice()) 

Notas de sintaxe:

 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) //   

Conversão implícita


Retornando ao exemplo de Float para Int:

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

Ao chamar double, temos uma incompatibilidade de tipo do parâmetro esperado (Int) com o parâmetro de entrada (Float). Portanto, o compilador está procurando por qualquer método no escopo, marcado como implícito e com o parâmetro esperado (Int) e o parâmetro de entrada (Float) necessários nessa situação. Localiza FloatToInt, executa a conversão e passa o valor desejado ainda mais para o dobro.

Agora, espero, ficou mais claro. Todo o sucesso em dominar Scala!

Source: https://habr.com/ru/post/pt451358/


All Articles