РЕДАКТИРОВАТЬ
ОК, @Drexin поднимает хороший вопрос: потеря безопасности типов / неожиданные результаты при использовании неявных преобразователей.
Как насчет менее распространенного преобразования, гдеконфликты с PreDef имплицитами не возникнут?Например, я работаю с JodaTime (отличный проект!) В Scala.В том же объекте пакета контроллера, где определены мои импликации, у меня есть псевдоним типа:
type JodaTime = org.joda.time.DateTime
и неявный, который преобразует JodaTime в Long (для DAL, построенного поверх ScalaQuery, где даты хранятся как Long)
implicit def joda2Long(d: JodaTime) = d.getMillis
Здесь не может быть двусмысленности между импликациями PreDef и моего пакета контроллера, и имплицитные контроллеры не будут фильтроваться в DAL, как это происходит в другой области пакета.Поэтому, когда я выполняю
dao.getHeadlines(articleType, Some(jodaDate))
, для меня, IMO, безопасно выполняется неявное преобразование в Long, и, учитывая, что запросы, основанные на дате, интенсивно используются, я сохраняю несколько шаблонов.
Аналогичнодля преобразований str2Int уровень контроллера получает параметры URI сервлета в виде String -> String.Во многих случаях URI тогда содержит числовые строки, поэтому, когда я фильтрую маршрут, чтобы определить, является ли String типом Int, я не хочу каждый раз stringVal.toInt;вместо этого, если регулярное выражение проходит, позвольте неявному преобразовать строковое значение в Int для меня.Все вместе это выглядело бы так:
implicit def str2Int(s: String) = s.toInt
get( """/([0-9]+)""".r ) {
show(captures(0)) // captures(0) is String
}
def show(id: Int) = {...}
В приведенных выше контекстах, являются ли эти допустимые варианты использования для неявных преобразований или же, более того, всегда явными?Если последнее, то каковы допустимые варианты использования неявного преобразования?
ORIGINAL
В объекте пакета у меня есть некоторые неявные преобразованияопределены, одна из них простая строка в Int:
implicit def str2Int(s: String) = s.toInt
Как правило, это работает нормально, методы, которые принимают параметр Int, но получают строку, делают преобразование в Int, как и методы, в которых тип возвращаемого значенияимеет значение Int, но фактическое возвращаемое значение - String.
Отлично, теперь в некоторых случаях ошибки компилятора с неявной страшной неявностью:
оба метода augmentString в объекте Predefтипа (x: String) scala.collection.immutable.StringOps и метод str2Int (s: String) Int являются возможными функциями преобразования из java.lang.String в? {val toInt:?}
Я знаю, что это происходит, когда я пытаюсь выполнить ручные встроенные преобразования строки в Int.Например, val i = "10".toInt
Мой обходной путь / хак был в том, чтобы создать помощника asInt вместе с последствиями в объекте пакета: def asInt(i: Int) = i
и использовать как, asInt("10")
Итак,Является ли неявная лучшая практика неявной (т.е. учиться, будучи обожженной), или есть какие-то руководящие принципы, которым нужно следовать, чтобы не попасть в ловушку собственного производства?Другими словами, следует ли избегать простых общих неявных преобразований и использовать только те, где тип для преобразования уникален?(т.е. никогда не попадет в ловушку неоднозначности)
Спасибо за обратную связь, последствия потрясающие ... когда они работают как положено; -)