Этот пост посвящен образцу, который демонстрирует способность Kotlin умело изменять параметры универсального типа .
Итак, рассмотрим сначала мир, где Kotlin не поддерживает эту функцию. Если бы мы использовали библиотеку Джексона для преобразования JSON в карту с ключами на основе строк и значениями на основе целых чисел, я бы использовал код в следующих строках:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@Test fun `sample parameterized retrieval raw object mapper`() { val objectMapper = ObjectMapper() val map: Map<String, Int> = objectMapper.readValue( "" " | { | "key1" : 1 , | "key2" : 2 , | "key3" : 3 | } "" ".trimMargin(), object : TypeReference<Map<String, Int>>() {}) assertThat(map).isEqualTo(mapOf( "key1" to 1 , "key2" to 2 , "key3" to 3 )) } |
Упомянутый выше TypeReference реализует шаблон, называемый токеном Super type, который позволяет захватывать тип параметризованного типа посредством подкласса. Обратите внимание на уродливый способ создания анонимного подкласса в Kotlin.
1
|
object : TypeReference<Map<String, Int>>() {} |
Я хотел бы вызвать ObjectMapper следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@Test fun `sample parameterized retrieval`() { val om = ObjectMapper() val map: Map<String, Int> = om.readValue( "" " | { | "key1" : 1 , | "key2" : 2 , | "key3" : 3 | } "" ".trimMargin()) assertThat(map).isEqualTo(mapOf( "key1" to 1 , "key2" to 2 , "key3" to 3 )) } |
Параметр универсального типа выводится на основе типа того, что должно быть возвращено (левая часть).
Это может быть достигнуто с помощью функции расширения ObjectMapper, которая выглядит следующим образом:
1
2
|
inline fun <reified T> ObjectMapper.readValue(s: String): T = this .readValue(s, object : TypeReference<T>() {}) |
Встроенная функция является основой поддержки возможности изменения параметра универсального типа здесь — после компиляции функция будет развернута в любое место, где вызывается эта функция, и, следовательно, вторая версия точно такая же, как и первая версия теста. но читает гораздо лучше, чем раньше.
Обратите внимание, что Джексон уже реализует эти функции расширения Kotlin в превосходной библиотеке jackson-module-kotlin .
Смотреть оригинальную статью здесь: Kotlin — Пример параметров Reified type
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |