Несоответствие типов. Обязательная карта <String, Any> Найдено карта <String, Any?>

Я пытаюсь выполнить select, используя расширение kotlin в kotlin как kotlin ниже.

 fun read() { database.use { select(PersonTable.Name).exec { select("myTable").exec() { parseList( object : MapRowParser<Map<String, Any>> { override fun parseRow(columns: Map<String, Any?>): Map<String, Any> { Log.d("Hello", "Hello") return columns; } } ) } } } } 

Я получаю сообщение об ошибке в return column

 Type mismatch. Required Map<String, Any> Found Map<String, Any?> 

Если я override fun parseRow(columns: Map<String, Any>): Map<String, Any> то он показывает ошибку.

введите описание изображения здесь

build.gradle

 apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.williams.fourthdemo" minSdkVersion 16 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" compile 'com.android.support:appcompat-v7:25.3.1' testCompile 'junit:junit:4.12' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile "org.jetbrains.anko:anko-common:0.10.1" compile "org.jetbrains.anko:anko-sqlite:0.10.1" } 

Это ошибка в библиотеке anko?

Выглядит как

object : MapRowParser<Map<String, Any>> {

должно быть действительно

object : MapRowParser<Map<String, Any?>> {

В базах данных очень часто есть столбцы, которые возвращают нуль в ячейке. То, как вы определили его как Any null, никогда не произойдет. Если вы вернетесь в Map<String, Any> то вы просто закончите с ошибками во время выполнения, если нуль будет содержаться где угодно.

Вам лучше всего подходит, сделав его Any? тип, который заставляет возвращаемый тип parseRow быть Map<String, Any?> также и исправляет потенциальную ошибку в вашем коде, которая произошла бы, если бы нулевое значение должно было где-то подкрадываться.

columns имеют тип Map<String, Any?> , обратите внимание, что Any? любой объект или null . Но возвращаемый тип метода – Map<String, Any> , Any не может быть null.

Например, вы можете отфильтровать входящую карту, оставив только ненулевые значения: columns.filterValues { it != null } as Map<String, Any> . Он содержит непроверенный актерский состав, но он безопасен.

Это не ошибка в Anko. Это ошибка в коде.

Эта функция неверна:

 override fun parseRow(columns: Map<String, Any?>): Map<String, Any> { Log.d("Hello", "Hello") return columns; } 

Вы берете ввод и возвращаете его как есть, но с другим типом.

Ваш ввод имеет тип Map<String, Any?> Но вы должны каким-то образом преобразовать его в Map<String, Any>

Было бы так, как если бы вы определили функцию, которая принимает String и возвращает Int следующим образом:

 fun parseString(s: String): Int { return s } 

Это, очевидно, не будет компилироваться.

Интерфейс, который вы пытаетесь реализовать, в основном:

 interface MapRowParser<out T> { fun parseRow(columns: Map<String, Any?>): T } 

Вы должны предоставить функцию, которая преобразует словарь, представляющий строку базы данных, в какой-то конкретный объект по вашему выбору. Но вы должны фактически предоставить код для обработки.

В качестве альтернативы, Anko предоставляет вам функцию, которая может автоматически сопоставлять строку таблицы с конструктором класса, что я бы предпочел использовать, вместо того, чтобы вручную сопоставлять словарные ключи с полями классов.

 data class User(val userId: Int, val userName: String) val rowParser = classParser<User>()