2012-01-30 27 views
17

escribo la siguiente conversión implícita en Scala:¿Por qué este tipo de conversión implícita es ilegal?

implicit def strToInt2(str: String):Int = { 
    str.toInt 
    } 

pero se eleva este error de compilación:

<console>:9: error: type mismatch; 
found : str.type (with underlying type String) 
required: ?{val toInt: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method augmentString in object Predef of type (x: String)scala.collection. 
immutable.StringOps 
and method toi in object $iw of type (str: String)Int 
are possible conversion functions from str.type to ?{val toInt: ?} 
      str.toInt 
     ^

Si quito el tipo de retorno, simplemente declaran así:

implicit def strToInt2(str: String) = { 
    str.toInt 
    } 

Compila con éxito. ¿Alguien puede decirme cuál es la diferencia entre los dos?

+0

No sé la respuesta exacta, pero supongo que hay una cadena de conversión implícita -> int en Predef. Entonces, agregar nuevas conversiones de ese tipo hace que las cosas sean ambiguas. – dmitry

Respuesta

17

Ok, vamos a empezar con el principio, ¿por qué fracasan en el primer caso:

  1. intenta definir un método implícito que transforma una String en un Int y para ello se llama a toInt.
  2. Desafortunadamente, toInt no es parte de la clase String. Por lo tanto, el compilador necesita encontrar un implícito para convertir str en algo que tenga un método toInt:Int.
  3. Afortunadamente, Predef.augmentString convierte un String en un StringOps, que tiene dicho método.
  4. Pero el tipo Int también tiene dicho método y como se define un tipo de retorno, el método strToInt2 se puede llamar recursivamente, y como el método es implícito, se puede aplicar para transformar algo con una función toInt:Int.
  5. El compilador no sabe qué método implícito a utilizar (entre el suyo y el Predef.augmentString y genera un error.

En el segundo caso, ya que se omite el tipo de retorno, la función strToInt2 no puede ser recursiva, y ya no hay dos candidatos para transformar el String

pero si después de esta definición, se intenta:. "2".toInt, el error está de vuelta:. ahora tiene dos formas de obtener algo con una función toInt:Int cuando se tiene un String

Cuestiones relacionadas