类型不匹配。 必需的地图<字符串,任何>找到的地图<字符串,任何?>

我试图执行选择使用下面的anko扩展

 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库中有这个bug吗?

好像

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

应该是真的

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

数据库中有一些在单元格中返回null的列是很常见的。 您将其定义为Any意味着null的方式永远不会发生。 如果您将您的返回转换为Map<String, Any>那么如果任何地方都包含null,您将只会发生运行时错误。

你最适合做一个Any? 强制parseRow返回类型为Map<String, Any?> ,并修复在您的代码中可能会出现的错误,如果null值会在某处出现。

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?>但是你必须以某种方式把它转换成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>()