2009-11-12 10 views
14

¿Hay algo que tengo mal en el siguiente fragmento: -conversión implícita de String a int en Scala 2,8

object Imp { 
    implicit def string2Int(s: String): Int = s.toInt 

    def f(i: Int) = i 

    def main(args: Array[String]) { 
    val n: Int = f("666") 
    } 
} 

me sale el siguiente desde el 2,8 compilador: -

información: Compilación completado con 1 error y 0 advertencias
Información: 1 error
Información: 0 advertencias
... \ Scala-2,8-tests \ src \ Imp.scala
error: error: la línea (4) error: tipo MISM atch;
encuentran: String
requerida: {val Toint:?}
Tenga en cuenta que las conversiones implícitas no son aplicables porque son ambiguas:
tanto string2Int método en el objeto Imp del tipo (s: String) Int
y el método augmentString en el objeto Predef de tipo (x: String) scala.collection.immutable.StringOps
son posibles las funciones de conversión de String a? {val toInt:?}
implicit def string2Int (s: String): Int = s.toInt

Respuesta

8

Hay ya una impli conversión cit. en el alcance, desde scala.Predef. No es necesario que declare su propia conversión implícita para agregar un método toInt a String. Tiene 3 opciones (me gustaría ir a la última!):

  • cambiar su nombre de método a algo así como asInt
  • UNIMPORT la conversión en Predef
  • No se moleste en la definición de su propia y el uso en cambio el toInt que viene incluido con la biblioteca Scala

Tenga en cuenta que Scala sólo hará uso de una conversión implícita dentro del alcance si es única.

+0

Gracias por la respuesta rápida, desafortunadamente el implícito de Predef no entra en juego si comento mi implícito anterior, solo parece estar en el alcance cuando aparece la competencia ;-) La opción toInt está bien, pero Estaba explorando una serie de conversiones de String en un método determinado por un parámetro de tipo, uno de ellos es String, es decir, no-op. –

+0

Tendré que probar esto mañana con 2.8. ¡Utilizo la conversión 'toInt' en el código de producción (es decir, usando 2.7) todo el tiempo! –

23

Lo que está sucediendo es que Java no define un método toInt en String. En Scala, lo que define ese método es la clase StringOps (Scala 2.8) o RichString (Scala 2.7).

Por otro lado, hay un método disponible en toIntInt también (a través de otra implícita, tal vez?), Por lo que el compilador no sabe si se va a convertir la cadena en StringOps, definido a través de la implícita, o al Int, a través de su propia implícita.

Para resolverlo, llame al implícito explícitamente.

object Imp { 
    implicit def string2Int(s: String): Int = augmentString(s).toInt 

    def f(i: Int) = i 

    def main(args: Array[String]) { 
    val n: Int = f("666") 
    } 
} 
+0

Gracias por la ayuda, no me había dado cuenta de que RichString ha sido reemplazado. Lo que todavía me confunde es que cuando no proporciono un implícito, la conversión a través de augmentString no se encuentra y se produce un error de tipo. Intento no utilizar una llamada explícita porque el tipo para convertir es proporcionado por un parámetro de tipo en el método real que intento escribir. –

+0

RichString no ha sido reemplazado, todavía existe. Sin embargo, no sé cuál es el problema con AugmentedString. El problema es que el compilador no sabe qué método ".toInt" llamar: el de AugmentedString o el de Int. –

+0

RichString todavía existe? Será mejor que revise esta clave de eliminación. – extempore

1

Creo que tengo una solución.

Si creo un RichString del argumento Cadena, la conversión implícita ocurre desde RichString a Int usando el método implícito que proporciono (esto funciona para 2.7.x y 2.8). Si elimino mi implícito, obtengo un error de tipo.

object Imp { 

    implicit def string2Int(rs: RichString): Int = rs.toInt 

    def f(i: Int) = i 

    def main(args: Array[String]) { 
    val n: Int = f(new RichString("666")) 

    println(n) 
    } 
} 

Todavía estoy confundido en cuanto a por qué tanto implícitos entraron en alcance y se enfrentaron cuando presentó una implícita y por qué la Predef uno no entran en el ámbito cuando no le proporcionamos una para cadena a En t. Supongo que la pregunta sobre una conversión implícita de String a Int permanece abierta.

Cuestiones relacionadas