繁体   English   中英

kotlin 函数返回 null

[英]kotlin function returning null

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

这是它的基本外观:

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
}

我真的必须实现我自己的游标并用无用的“throw UnsupportedExceptions”来弄乱我的代码吗?

您的选择是:

  • 如果cursornull ,则抛出异常: return cursor!! (这是可以的,以防您确定cursor实际上从未为null
  • 如果cursornull ,则返回一些简单的游标(例如,您自己的AbstractCursor实现,它表现为空结果集
  • (正如 Franck 在他的评论中所说)将QueryBuilder.query()函数注释为@NotNullhttp : QueryBuilder.query()

有围绕这个主题构建的库:

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 很好的替代品。

使用空值也很好,在这些情况下,有许多运算符可以帮助处理空值。 在 Kotlin 中,处理可空值、引用或转换它们的惯用方法是什么是另一篇涵盖可空性的 SO 帖子,一般解释了一些可用的运算符(包括此处某些答案中使用的“安全调用”运算符)。

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

并将返回类型设置为 Cursor?

这就是我通常的做法。 不知道是好是坏。

也许你可以将函数 end : Cursor 更新为 : Cursor? 例子:

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

实际上有一个 hack 可以让你欺骗 Kotlin 编译器接受null作为不可为空的引用。

NullHack.java :

public class NullHack {
    private NullHack() {
    }

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

空黑客.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()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM