GMS Task<TResult> class:如果 isSuccessful(),getResult() return 可以为 null 吗?
GMS Task<TResult> class: can getResult() return null if isSuccessful()?
最近对 GMS 任务库进行了 @Nullable 更改。反编译后的前几行.class 看起来像
public abstract class Task<TResult> {
public Task() {
}
public abstract boolean isComplete();
public abstract boolean isSuccessful();
public abstract boolean isCanceled();
@Nullable
public abstract TResult getResult();
之前编译的 Kotlin 代码:
if (task.isSuccessful) {
task.result.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
}
更新一些 gms play-services-zzz
依赖项后,代码现在有编译错误:
LoginActivity.kt: (148, 28): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type AuthResult?
问题是,isSuccessful() == true
是否意味着getResult != null
?或者将 if 测试更改为 if (task.result != null)
?
会更好吗?
您看到的是 Kotlin 编译器无法根据 isSuccessful 的结果将结果智能转换为 NonNull 类型,这可能在与 Java 和 Kotlin 代码交互时发生。
在 Kotlin 1.3 中,语言中添加了 "Contracts" 的实现,以允许开发人员以 IDE 可用于静态分析和推断类型的格式添加有关方法的元数据(智能投射)。
参见第 1.2 节 "Returns and Implies" https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c
所以对于合同,如果实现看起来像这样,它会正确地智能投射:
open class Task<T> {
var result: T? = null
private set
fun isSuccessful(): Boolean {
contract {
returns(true) implies (result != null)
}
return result != null
}
}
然而,在你的情况下,你可能想使用另一个安全调用运算符 ?
并使用 Elvis 运算符 ?:
调用你的 !task.isSuccessful
代码,如下所示:
if (task.isSuccessful) {
task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
} ?: handleFailure() // Defensively call just in case
} else {
handleFailure()
}
有 GMS 任务可以在运行时 return null。例如FirebaseAnalytics.getAppInstanceId()
所以你应该检查结果是否为空,而不是依赖注释。
最近对 GMS 任务库进行了 @Nullable 更改。反编译后的前几行.class 看起来像
public abstract class Task<TResult> {
public Task() {
}
public abstract boolean isComplete();
public abstract boolean isSuccessful();
public abstract boolean isCanceled();
@Nullable
public abstract TResult getResult();
之前编译的 Kotlin 代码:
if (task.isSuccessful) {
task.result.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
}
更新一些 gms play-services-zzz
依赖项后,代码现在有编译错误:
LoginActivity.kt: (148, 28): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type AuthResult?
问题是,isSuccessful() == true
是否意味着getResult != null
?或者将 if 测试更改为 if (task.result != null)
?
您看到的是 Kotlin 编译器无法根据 isSuccessful 的结果将结果智能转换为 NonNull 类型,这可能在与 Java 和 Kotlin 代码交互时发生。
在 Kotlin 1.3 中,语言中添加了 "Contracts" 的实现,以允许开发人员以 IDE 可用于静态分析和推断类型的格式添加有关方法的元数据(智能投射)。
参见第 1.2 节 "Returns and Implies" https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c
所以对于合同,如果实现看起来像这样,它会正确地智能投射:
open class Task<T> {
var result: T? = null
private set
fun isSuccessful(): Boolean {
contract {
returns(true) implies (result != null)
}
return result != null
}
}
然而,在你的情况下,你可能想使用另一个安全调用运算符 ?
并使用 Elvis 运算符 ?:
调用你的 !task.isSuccessful
代码,如下所示:
if (task.isSuccessful) {
task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
} ?: handleFailure() // Defensively call just in case
} else {
handleFailure()
}
有 GMS 任务可以在运行时 return null。例如FirebaseAnalytics.getAppInstanceId()
所以你应该检查结果是否为空,而不是依赖注释。