Flutter MethodCall 以 kotlin 方式进行非零检查

Flutter MethodCall non-nil check in kotlin way

我尝试用kotlin做一个MethodCall类型判断函数,但是return对我来说类型不匹配,我应该怎么解决?

import java.util.Objects

import io.flutter.plugin.common.MethodCall

class Utils private constructor() {
    companion object {
        fun getDoubleArgument(call: MethodCall, argument: String?): Double {
            return try {
                if (call.argument<Any>(argument) is Double) {
                    Objects.requireNonNull(call.argument<Double>(argument))!!  // The call.argument return Double? type, but when I add !! assert, it report Unnecessary non-null assertion (!!).
                } else if (call.argument<Any>(argument) is Long) {
                    val l = Objects.requireNonNull(call.argument<Long>(argument))
                    l!!.toDouble()
                } else if ...
        }

本人不使用Flutter,如有错误请多多包涵

在 Kotlin 中不需要 Objects.requireNonNull(),因为 !! 已经做了与 requireNonNull() 完全相同的事情,除了它抛出 KotlinNullPointerException 而不是 NullPointerException。它不起作用的原因是 Kotlin 不知道 Java 方法保证 return 一个非空值。

class Utils private constructor() {
    companion object {
        fun getDoubleArgument(call: MethodCall, argument: String?): Double {
            return try {
                if (call.argument<Any>(argument) is Double) {
                    call.argument<Double>(argument)!!
                } else if (call.argument<Any>(argument) is Long) {
                    call.argument<Long>(argument)!!.toDouble()
                } else if ...
        }

最好一次性获取参数并使用该值。然后你可以依靠 Kotlin smart-casting 来简化代码:

class Utils private constructor() {
    companion object {
        fun getDoubleArgument(call: MethodCall, argument: String?): Double {
            val arg = call.argument<Any>(argument)
            return try {
                if (arg is Double) {
                    arg
                } else if (arg is Long) {
                    arg.toDouble()
                } // ...
                else if (arg == null) {
                    0.0
                } else {
                    error("unsupported argument type")
                }
        }

您可以使用 when 语句而不是 else if 链来使其更易于阅读:

class Utils private constructor() {
    companion object {
        fun getDoubleArgument(call: MethodCall, argument: String?): Double {
            val arg = call.argument<Any>(argument)
            return try {
                when (arg) {
                    is Double -> arg
                    is Long -> arg.toDouble()
                    // ...
                    null -> 0.0
                    else -> error("unsupported argument type")
                }
            }
        }