Неявное преобразование из String в Int в 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")
  }
}

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

Информация: компиляция завершена с 1 ошибкой и 0 предупреждениями Информация: 1 ошибка
Информация: 0 предупреждений
... \scala -2.8-тесты\SRC\Imp.scala
  Ошибка: ошибка: строка (4) ошибка: тип несоответствия;
найдено: Строка
требуется:? {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

Ответы

Ответ 1

Что происходит, так это то, что 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")
  }
}

Ответ 2

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

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

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

Ответ 3

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

Если я создаю 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)
  }
}

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