Почему этот тип неявного преобразования является незаконным? - PullRequest
17 голосов
/ 30 января 2012

Я пишу следующее неявное преобразование в scala:

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

Но возникает эта ошибка компиляции:

<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
           ^

Если я удаляю возвращаемый тип, просто объявите его следующим образом:

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

Успешно компилируется.Может кто-нибудь сказать мне, в чем разница между этими двумя?

1 Ответ

17 голосов
/ 30 января 2012

Хорошо, давайте начнем с начала, почему в первом случае происходит сбой:

  1. Вы пытаетесь определить неявный метод, который преобразует String в Int и сделатьпоэтому вы звоните toInt.
  2. К сожалению, toInt не является частью класса String.Таким образом, компилятору нужно найти неявное преобразование str во что-то, что имеет метод toInt:Int.
  3. К счастью, Predef.augmentString преобразует String в StringOps, который имеет такойmethod.
  4. Но у типа Int также есть такой метод, и КАК вы определяете тип возвращаемого значения, метод strToInt2 можно вызывать рекурсивно, а поскольку метод неявный, его можно применять для преобразования.что-то с toInt:Int функцией.
  5. Компилятор не знает, какой неявный метод использовать (между вашим и Predef.augmentString, и выдает ошибку.

Во втором случае, так как вы опускаете возвращаемый тип, функция strToInt2 не может быть рекурсивной, и больше нет двух кандидатов для преобразования String.

НО, если после этого определения вы попытаетесь: "2".toInt,ошибка вернулась: теперь у вас есть два способа получить что-то с помощью функции toInt:Int, если у вас есть String.

...