Как указать тип цели для литералов коллекции?

Я пытаюсь использовать целевой тип, чтобы указать тип литерала коллекции:

val java.util.HashMap<String,String> map = #{
  'a' -> 'b'
}

Но я получаю:

HelloWorld.java:212: error: incompatible types: Set<Object> cannot be converted to HashMap<String,String>
    final HashMap<String, String> map = Collections.<Object>unmodifiableSet(CollectionLiterals.<Object>newHashSet(_mappedTo, _mappedTo_1, _mappedTo_2, _mappedTo_3));

Обратите внимание, что это ошибка компиляции Java, а не Xtend. По какой-то причине Xtend пытается сгенерировать Set, хотя целевой тип — HashMap.

Однако, если я изменю целевой тип на Map, он сгенерирует карту, как и ожидалось.

В документах Xtend говорится

Кроме того, xtend поддерживает литералы коллекций для создания неизменяемых коллекций и массивов в зависимости от целевого типа.

поэтому я подумал, что могу контролировать тип неизменяемой карты, которую я получаю.

Расширенная версия: 2.9.0


person Kelvin    schedule 05.07.2016    source источник


Ответы (2)


Вы не можете сделать так, как хотите - неявное преобразование не изменит для вас тип литерала карты (ошибка, которую вы получаете, - это артефакт компилятора - он путается между набором пар и литералами карты). Что вы можете сделать вместо этого, это

val map = Maps.newHashMap(#{
        'a' -> 'b'
    })

что, вероятно, еще меньше печатать ;) Карты взяты из com.google.common.collect, которые вы получите вместе с xtend в зависимостях.

person Artur Biesiadowski    schedule 13.07.2016
comment
Хороший. Увидев ваш ответ, я нашел похожее решение для чистой Java. - person Kelvin; 13.07.2016

Эта цитата из документа Xtend:

Кроме того, xtend поддерживает литералы коллекций для создания неизменяемых коллекций и массивов в зависимости от целевого типа.

означает либо коллекцию, или массив, поскольку для обоих буквальный синтаксис одинаков:

val myList = #['Hello', 'World']
val String[] myArray = #['Hello', 'World']

Наборы и карты имеют разный синтаксис, поэтому здесь не нужно указывать целевой тип:

val mySet = #{'Hello', 'World'}
val myMap = #{'a' -> 1, 'b' -> 2}

Если вы настаиваете на целевом типе, используйте, например. newHashMap:

val myHashMap = newHashMap('a' -> 1, 'b' -> 2)
person charlie    schedule 29.07.2016