kotlin函数返回null

我正在尝试一些与kotlin的android开发。 在我的情况下,我想覆盖:ContentProvider我必须覆盖函数“查询”。 “查询”返回“光标”类型。 但是,当我用database.query在函数中创建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 } 

我真的必须实现我自己的光标,并用无用的“抛出UnsupportedExceptions”杂乱我的代码?

您的选择是:

  • 如果cursornull ,则抛出一个异常: return cursor!! (如果您确定cursor永远不会实际为null ,则这是可以的
  • 如果cursornull ,则返回一些简单的游标(例如,您自己的AbstractCursor实现,其行为如空结果集
  • (正如弗兰克在评论中所说的那样)将QueryBuilder.query()函数注释为@NotNull : http : QueryBuilder.query()

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

Kotlin的Result库提供了一个很好的方法来处理基于响应值的“做这个或那个”的情况。 并有一个真正的回应和异常或无效的回应,这是你正在寻求。

对于Promise ,你可以在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. } 

作为失败类型,承诺并不总是必须有错误。 他们可以是任何你想要的。 错误代码,错误消息,数据类或异常(如果您愿意)。

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

这些都是OptionalMaybe Kotlin替代品。

使用空值也是很好的,在这种情况下有很多操作符可以帮助处理空值。 在Kotlin中,处理可空值的惯用方法,引用或转换它们是另一个SO职位,涵盖一些可用的操作符(包括这里的一些答案中使用的“安全调用”操作符)。

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

并把返回类型光标?

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

实际上有一个黑客可以让你欺骗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() }