2015-08-31 5 views
2

Там в этом вопрос для Java How to declare a map with variable generics?Карта элементов с переменными дженерик

У меня точно такая же проблема. Есть ли лучший способ/Скала решить его?

EDIT: Я попытался выполнить приведенный выше ответ, но без реализации внутренней карты.

private class SectionConversionMap 
    extends HashMap[SectionSchema[_], (Iterable[HtmlRow]) => Option[Iterable[_]]] 
{ 
    override def +[T, B1 >: (Iterable[HtmlRow]) => 
    Option[Iterable[T]]](kv: (SectionSchema[T], B1)): 
    HashMap[SectionSchema[_], B1] = { 
    val m = super.+(kv) 
    m 
    } 
} 

Но мой IDE продолжает настаивать, что Expression of type HashMap[SectionSchema[_], Any] doesn't conform to expected type HashMap[SectionSchema[_], B1]

+0

Действительно ли это имеет значение? – Andrey

+0

Ну, пойдем с основами - неизменный HashMap – Andrey

ответ

1

Вот простой пример, может быть, это может дать вам подсказку:

import scala.collection.mutable._ 
class MyMap extends HashMap[Any, List[Any]] { 
    def put[T, B <% T](key: T, value: List[B]) = { 
    this += key -> value 
    } 
} 
val b = new MyMap() 
b.put("q", List("q")) 
b.put(12, List(12)) 
b.put(122, List("23")) //not compile 

Последняя строка не будет компилировать:

No implicit view available from String => Int.  

Кажется, что вы хотите выполнить ovrride стандартную sc ala lib, однако, я думаю, вы не могли бы изменить типы возвращаемых методов, если хотите сделать переопределение. Ниже Ла Скала Карта Метод

@migration("`+` creates a new map. Use `+=` to add an element to this map and return that map itself.", "2.8.0") 
    def + [B1 >: B] (kv: (A, B1)): Map[A, B1] = clone().asInstanceOf[Map[A, B1]] += kv 

я сделал что-то подобное в вашем коде, и он может скомпилировать сейчас, надеюсь, это то, что вам нужно или дать вам подсказку:

import scala.collection.mutable._ 
type HtmlRow = String 
type SectionSchema[T] = List[T] 
private class SectionConversionMap extends HashMap[SectionSchema[_], (Iterable[_]) => Option[Iterable[_]]] { 
    def +[T, B1 >: (Iterable[HtmlRow]) => Option[Iterable[T]]](kv: (SectionSchema[T], B1)): 
     HashMap[SectionSchema[_], B1] = { 
     val m = clone().asInstanceOf[HashMap[SectionSchema[_], B1]] 
     m+=kv 
     } 
} 
+0

Не могли бы вы расширить свой ответ на случай в моем редактировании? Спасибо. – Andrey

+0

Обратите внимание, что этот 'def +' не переопределяет старое (в противном случае вам понадобится ключевое слово override). –

+0

@Binzi, без переопределения, откуда я узнаю, что карта всегда будет содержать корректно парные значения - '[T, B1>: (Iterable [HtmlRow]) => Опция [Итерируемая [T]]] (kv: (SectionSchema [ T], B1)) ', а не более общей подписи? – Andrey

2

Не выдвигайте стандартные типы коллекций, это просто требует неприятностей, если вы не знаете, что вы делаете. В этом случае компилятор будет гарантировать, что все сигнатуры методов не менее общие, как и раньше, и ваш + не является (обратите внимание, что в ответе Бинзи Цао он ничего не отменяет!). Просто следуйте за источником и держите Map в поле.

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