Implicits no scala
Olá Pessoal, estou voltando a publicar alguns rascunhos que tinha aqui de scala.
Você já deve ter cruzado em sua vida com funções/métodos que possuem parâmetros “default”. Eles também existem no Scala.
scala> def soma(n: Int = 1, m: Int = 2) = n + m soma: (n: Int, m: Int)Int
Usando os dois valores defaults.
scala> soma() res2: Int = 3
Agora só o segundo será o default.
scala> soma(2) res3: Int = 4
Sem usar default.
scala> soma(2, 3) res4: Int = 5
O Scala também apresenta um tipo de parâmetro/operação implícito. Algo como as conversões implícitas que vemos frequentemente.
A beleza aqui é poder construir seu próprio conversor ou passar parâmetros de forma implícita, com a instrução “implicit”. Veja este outro exemplo.
scala> def quadradoImplicito (implicit num: Int) = num * num quadradoImplicito: (implicit num: Int)Int
É possível usar normalmente, como estamos acostumados.
scala> quadradoImplicito(3) res0: Int = 9
Até agora funcionou exatemente como esperado. O que muda?
Vamos tentar chamar a função sem passar parâmetro.
scala> quadradoImplicito <console>:26: error: could not find implicit value for parameter num: Int quadradoImplicito ^
E por fim a mágica: vamos declarar um variável implícita do tipo que a função recebe. A função usará este valor como default.
scala> implicit val m = 5 m: Int = 5 scala> quadradoImplicito res2: Int = 25
Vejamos, por fim, como construir nosso próprio conversor implícito. Vamos imaginar um cenário em que passamos para nosso método “soma”, criado acima, duas listas:
scala> val myList1 = List(1, 2, 3) myList1: List[Int] = List(1, 2, 3) scala> val myList2 = List(4, 5) myList2: List[Int] = List(4, 5) scala> soma(myList1, myList2) <console>:30: error: type mismatch; found : List[Int] required: Int soma(myList1, myList2) ^ <console>:30: error: type mismatch; found : List[Int] required: Int soma(myList1, myList2) ^
Obviamente, o método não sabe o que fazer. Para este caso, criaremos um método implícito que converterá a List em Int.
scala> implicit def list2Int(lista: List[Int]): Int = lista.sum warning: there was one feature warning; re-run with -feature for details list2Int: (lista: List[Int])Int
Agora a sacada: desta forma, sempre que invocarmos um método que espera um Int e recebe uma List[Int], ele fará automagicamente a conversão transformando a lista em um inteiro (soma de seus elementos).
scala> soma(myList1, myList2) res1: Int = 15
O que achou? Interessante, não?
Até a proxima.