parâmetros de tipo e alargamento numérico
Como sabemos, podemos adicionar (subtrair / multiplicar / etc.) Dois números de diferentesNumeric
tipos e o resultado será o mais amplo dos dois tipos, independentemente de sua ordem.
33F + 9L // Float + Long == Float
33L + 9F // Long + Float == Float
Isso ocorre porque cada um dos 7Numeric
classes (Byte
, Short
, Char
, Int
, Long
, Float
, Double
) tem 7 diferentes+()
métodos (e-()
, *()
, etc), um para cadaNumeric
tipo que pode ser recebido como um parâmetro passado. [Há um extra+()
método para lidar com umString
parâmetro, mas isso não precisa nos preocupar ele, re.]
Agora considere o seguinte:
implicit class PlusOrMinus[T: Numeric](a: T) {
import Numeric.Implicits._
def +-(b: T) = if (util.Random.nextBoolean) a+b else a-b
}
Isso funciona se os dois operandos são do mesmo tipo, mas também funciona se o tipo do 1º operando for maior que o tipo do 2º.
11F +- 2L // result: Float = 9.0 or 13.0
Eu acredito que o que está acontecendo aqui é que o compilador usafraca conformidade alcançaralargamento numérico no 2º operando (ob
parâmetro) conforme é passado para o+-()
método.
Mas o 1º operando não será ampliado para corresponder ao 2º. Nem compilará.
11L +- 2F // Error: type mismatch; found: Float(2.0) required: Long
Existe alguma maneira de contornar essa limitação?
Não posso usar um parâmetro de tipo diferente para ob
argumento (def +-[U: Numeric](b: U) = ...
) porque umNumeric
, expresso por meio de um parâmetro de tipo, só pode adicionar / subtrair seu próprio tipo.
É a única solução para criar 7 classes diferentes (PlusOrMinusShort/Int/Long/
etc.) com 7 métodos diferentes (def +-(b:Short)
, def +-(b:Int)
, def +-(b:Long)
etc.)?