Неявное преобразование из 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 остается открытым.