2013-07-03 3 views
1

Может кто-нибудь сказать мне, почему, как показано ниже, неявное преобразование работает при простом создании объекта KeyVal, но не работает при создании ключа на карте, которая является KeyVal.Использование implicits для ключей карты scala

спасибо.

object o { 
    case class KeyVal(i: Int) 
    object KeyVal { 
    implicit def strToKeyVal(s:String) = KeyVal(s.toInt) 
    } 
} 

import o._ 

val x : KeyVal = "1" // Works fine to create a KeyVal 

val x : Map[KeyVal, String] = Map("1" -> "One") // Type Mismatch: found (String, String), wants (KeyVal, String) 

ответ

3

Scala компилятор не является очень важной вещью, и он не может разрешить все типы ошибок типа. Как следует преобразовать (String, String) tuple в (KeyVal, String) кортеж и почему бы не (String, KeyVal) или (KeyVal, KeyVal). Ваше неявное преобразование конвертирует String в KeyVal, но не (String, String) в KeyVal. Если добавить это неявное преобразование к объекту компаньона:

implicit def strToKeyVal(s: (String, String)): (KeyVal, String) = (KeyVal(s._1.toInt), s._2) 

все будет работать нормально

+0

Спасибо. Я предполагаю, что он должен знать, что только первый член Tuple должен быть преобразован слишком много. Однако я не думал, что это было необоснованно, поскольку он должен знать, что первым членом Tuple был KeyVal, поскольку значение было Map [KeyVal, String] – user1922871

3

Это всего лишь вопрос времени. К тому времени, когда рассматривается тип Map, у вас больше нет String, но кортеж (String, String). Это происходит потому, что -> - это оператор, который применяется сначала, а затем его результат возвращается для Map.

Если вы не использовать этот оператор, он работает:

val x : Map[KeyVal, String] = Map(("1", "One")) 
+0

Это имеет смысл. Альтернатива, с которой я столкнулся, заключалась в использовании неявного класса KeyVal (s: String), который имеет метод: def hold (contents: String) = (this -> contents) Затем карту можно определить как Map [KeyVal, String ] = Карта («1» имеет значение «Один»). Это работает для меня, поскольку KeyVal - это на самом деле колодцы на тарелке, поэтому он говорит, что колодец содержит некоторое содержимое. Спасибо всем за хорошие ответы. – user1922871

Смежные вопросы