kotlin函数返回null

时间:2014-05-29 21:40:23

标签: null return kotlin kotlin-null-safety

我正在尝试使用kotlin进行一些android开发。在我的情况下,我想覆盖:ContentProvider,我必须覆盖函数"查询"。 "查询"返回"光标"类型。但是,当我在带有database.query的函数中创建Cursor实例时,我得到一个" Cursor?"类型。所以我只能返回Cursor,如果它不是null,但如果它是null,我该怎么办?

这基本上就是这样:

override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor {

    val cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder)
            // make sure that potential listeners are getting notified
            cursor?.setNotificationUri(getContext()?.getContentResolver(), uri)

            if(cursor != null)
                return cursor
            else
                // what to do here?

任何想法如何解决?

谢谢, 斯文

更新 首先感谢答案。

注释似乎不能在我的情况下工作,因为我只能访问已编译的代码,我没有选择注释源。也许我在这里遗漏了一些东西。

实现我自己的光标看起来有点矫枉过正,特别是每次出现问题时我都必须这样做。

所以看来我唯一的选择是返回光标!!但我不知道究竟是怎么做到的。我的代码比我的例子复杂一点,我错过了一个when语句。这是一个更新版本:

override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor {

    val cursor = ??? //how to initialize cursor somehow?
    val db = database.getWritableDatabase()

    if(db != null) {
        val cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder)
                // make sure that potential listeners are getting notified
                cursor?.setNotificationUri(getContext()?.getContentResolver(), uri)

                if(cursor != null)
                    return cursor
     }

    // return what here? cursor does not exist
}

我是否真的必须实现自己的光标并使我的代码混乱无用&#34;抛出UnsupportedExceptions&#34;?

5 个答案:

答案 0 :(得分:1)

您的选择是:

  • 如果cursornull,则抛出异常:return cursor!!(如果您确定cursor实际上从未null
  • 如果cursornull,请返回一些微不足道的光标(例如您自己的AbstractCursor实现,其行为为空结果集
  • (正如Franck在评论中所说)将QueryBuilder.query()函数注释为@NotNullhttp://blog.jetbrains.com/kotlin/using-external-annotations/

答案 1 :(得分:1)

围绕这个主题建立了一些库:

Kotlin的Result库提供了一种很好的方法来处理基于响应值“执行此操作”的情况。并且要获得真正的回应以及您正在寻求的异常或无效响应。

对于Promises,您可以在Kovenant库中找到相同的内容。随着Kovenant承诺可以立即解决,而不必是异步。所以它作为一般用途“我有一个结果,或没有”库。

// ... in my function that returns Promise<Cursor, String>
if (good) {
   return Promise.ofSuccess<Cursor, String>(cursor)
}
else {
   return Promise.ofFail<Cursor, String>("no database connection")
}

然后在函数的调用者中:

myFuncMakingACursor() success { cursor ->
    //called when all is ok, and I have a cursor
} fail {
    //called when promise is rejected
} always {
    //no matter what result we get, this is always called once.
}

Promise并不总是必须有错误作为失败类型。它们可以是你想要的任何东西。如果您愿意,可以输入错误代码,错误消息,数据类或异常。

这两个库都为您提供了从单个函数返回替代结果的方式,以及根据结果分支代码的方式

这些是OptionalMaybe的好Kotlin替代品。

使用空值也很好,并且在这些情况下有许多运算符可以帮助处理空值。 In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them是另一个涵盖可空性的SO帖子,一般性地解释了一些可用的运算符(包括这里的一些答案中使用的“安全呼叫”运算符)。

答案 2 :(得分:0)

if (db != null){
    //...
} else {
    return null
}

并将返回类型设置为Cursor?

这就是我通常做的事情。不知道它是坏还是坏。

答案 3 :(得分:-1)

也许可以将功能end:Cursor更新为:Cursor? 例如:

override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {}

答案 4 :(得分:-3)

实际上有一个hack允许你欺骗Kotlin编译器接受null作为非可空引用。

<强> NullHack.java

public class NullHack {
    private NullHack() {
    }

    @SuppressWarnings("ConstantConditions")
    @NotNull
    public static <T> T nullHack(@Nullable T object) {
        return object;
    }
}

<强> NullHack.kt

fun <T> T?.nullHack(): T = NullHack.nullHack(this)

然后在ContentProvider子类中,您可以编写以下代码:

override fun query(uri: Uri, projection: Array<out String>?, selection: String?,
        selectionArgs: Array<out String>?, sortOrder: String?): Cursor {

    val db = database.getWritableDatabase()!!
    val cursor = queryBuilder.query(db, projection, selection, selectionArgs,
            null, null, sortOrder)
    // make sure that potential listeners are getting notified
    cursor?.setNotificationUri(getContext()?.getContentResolver(), uri)
    return cursor.nullHack()
}