首页 文章

Kotlin:不能同时应用两个条件检查“返回体”功能样式

提问于
浏览
3

我有一个简单的功能检查,如下所示:

fun parseValidBluetoothBrickedId(controllerId: String?): Boolean{
    if(controllerId != null){
        if(controllerId.startsWith(BLUETOOTH_NAME_PREFIX) && controllerId.length > BLUETOOTH_NAME_PREFIX.length)
            return true
    }

    return false
}

我想将它转换为更简单的风格:

fun parseValidBluetoothBrickedId(controllerId: String?) =
        controllerId?.length > BLUETOOTH_NAME_PREFIX.length
      &&  controllerId?.startsWith(BLUETOOTH_NAME_PREFIX)

但IDE(Android Studio 3.0 Beta7)给我一个错误,强调大于('>')运算符:

操作员调用对应于点限定调用'controllerId?.length.compareTo(BLUETOOTH_NAME_PREFIX.length),此处不允许

它还强调为错误行controllerId?.startsWith(BLUETOOTH_NAME_PREFIX)并说:

类型不匹配 . 必需:Boolean,Found Boolean?

有什么问题,真的吗?它只是一个简单的方法,适用于第一个块if-else风格 .

3 回答

  • 2

    你不能在 controllerId?.length 上调用 compareTo (使用 < 运算符),因为它的类型是 Int? ,这意味着它可能是 null ,在这种情况下它不能作为数字进行比较 .

    类似地, controllerId?.startsWith(BLUETOOTH_NAME_PREFIX) 调用返回 Boolean? (因为它将返回 null ,如果 controllerIdnull ),它不能传递给 && 运算符,只能返回真正的 Boolean .

    这里的解决方案是使用原始方法执行 null 检查,并依靠智能转换将 controllerId 转换为 String 来摆脱安全调用:

    fun parseValidBluetoothBrickedId(controllerId: String?): Boolean =
            controllerId != null 
            &&  controllerId.length > BLUETOOTH_NAME_PREFIX.length
            &&  controllerId.startsWith(BLUETOOTH_NAME_PREFIX)
    
  • 6

    当你做 controllerId?.length 时,你得到一个 Int? . 您无法将 IntInt? 进行比较 . 这就是你得到第一个错误的原因 .

    您收到另一个错误,因为 controllerId?.startsWith(BLUETOOTH_NAME_PREFIX) 返回 Boolean? . 您不能在可以为null的参数上使用 && 运算符 . 它需要两个类型为 Boolean 的参数 .

    要解决这些问题,首先需要检查 controllerId != null . 这将智能转换 controllerId 为非可空类型 String . 像这样:

    fun parseValidBluetoothBrickedId(controllerId: String?): Boolean =
        controllerId != null
            && controllerId.startsWith(BLUETOOTH_NAME_PREFIX)
            && controllerId.length > BLUETOOTH_NAME_PREFIX.length
    
  • 1

    您转换的函数缺少 null 检查:

    fun parseValidBluetoothBrickedId(controllerId: String?) =
            controllerId != null && controllerId.length > "".length
                    && controllerId.startsWith("")
    

    与第一个示例一样,编译器必须进行空检查才能知道 controllerId 不是 null . 检查后,编译器使用"smart casting"并且调用是安全的 . 因此,检查后您不必使用 ?. 表示法 .

相关问题