Неявное преобразование из String в Int в Scala 2.8 - PullRequest
14 голосов
/ 13 ноября 2009

Есть ли что-то, что я ошибся в следующем фрагменте: -

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")
  }
}

Я получаю следующее от компилятора 2.8: -

Информация: компиляция завершена с 1 ошибкой и 0 предупреждениями
Информация: 1 ошибка
Информация: 0 предупреждений
... \ 2.8-Scala-тесты \ SRC \ Imp.scala
Ошибка: ошибка: строка (4) ошибка: несоответствие типов;
найдено: String
требуется:? {val toInt:?}
Обратите внимание, что неявные преобразования неприменимы, потому что они неоднозначны:
оба метода string2Int в объекте Imp типа (s: String) Int
и метод augmentString в объекте Predef типа (x: String) scala.collection.immutable.StringOps
возможны функции преобразования из String в? {val toInt:?}
неявный def string2Int (s: String): Int = s.toInt

Ответы [ 3 ]

23 голосов
/ 13 ноября 2009

То, что происходит, - то, что Java не определяет toInt метод на String. В Scala этот метод определяет класс StringOps (Scala 2.8) или RichString (Scala 2.7).

С другой стороны, существует метод toInt, доступный также и на Int (возможно, через другое неявное имя), поэтому компилятор не знает, нужно ли преобразовывать строку в StringOps через определенный неявный или Int через ваш собственный неявный.

Чтобы решить эту проблему, вызовите явное явное.

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")
  }
}
8 голосов
/ 13 ноября 2009

Существует уже неявное преобразование в области действия , из scala.Predef. Вам не нужно объявлять собственное неявное преобразование, чтобы добавить toInt метод к String. У вас есть 3 варианта (я бы выбрал последний!):

  • Измените имя вашего метода на что-то вроде asInt
  • Не импортировать преобразование в Predef
  • Не утруждайте себя определением и используйте вместо этого toInt, который поставляется в комплекте с библиотекой scala

Обратите внимание, что scala будет использовать неявное преобразование в области действия, только если оно уникально .

1 голос
/ 14 ноября 2009

Я думаю, у меня есть обходной путь.

Если я создаю RichString из аргумента String, неявное преобразование происходит из RichString в Int с использованием неявного метода, который я предоставляю (это работает для 2.7.x и 2.8). Если я удаляю неявное, я получаю ошибку типа.

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

Я все еще не понимаю, почему оба имплицита вошли в область видимости и столкнулись, когда я предоставил неявный, и почему почему Predef не попал в контекст, когда я не предоставил один для String для Int. Я полагаю, что вопрос о неявном преобразовании из String в Int остается открытым.

...