类型不匹配。必需的地图<string,any =“”>找到地图<string,any?=“”>

时间:2017-06-11 20:06:53

标签: android sqlite kotlin anko

我正在尝试使用anko中的kotlin扩展程序执行select,如下所示

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>,则会显示错误。

enter image description here

的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库中的错误吗?

3 个答案:

答案 0 :(得分:2)

columns的类型为Map<String, Any?>,请注意Any?是任何对象或null。但方法的返回类型为Map<String, Any>Any不能为空。

例如,您可以过滤传入的地图,只留下非空值:columns.filterValues { it != null } as Map<String, Any>。它包含一个未经检查的演员表,但它很安全。

答案 1 :(得分:1)

看起来像

functionReady: function() { selectors = $("ul.alternates > li"); $(selectors).off('click').on('click', function() { var sampleData = $(this).text(); insertText(sampleData); }); }

应该是

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

数据库通常具有在单元格中返回null的列。您将其定义为object : MapRowParser<Map<String, Any?>> {的方式意味着null永远不会发生。如果您将返回值转换为Any,那么如果在任何地方包含null,则最终会发生运行时错误。

最适合将它设为Map<String, Any>类型,强制parseRow返回类型为Any?并修复代码中可能出现的错误,如果null值为creep则会发生某处。

答案 2 :(得分:1)

这不是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>()