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

时间:2017-10-09 08:43:56

标签: kotlin kotlin-null-safety

我有一个简单的功能检查:

    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 个答案:

答案 0 :(得分:7)

您无法在compareTo上致电<(使用controllerId?.length运营商),因为其类型为Int?,这意味着它可能是null ,在这种情况下,它不能作为数字进行比较。

同样,controllerId?.startsWith(BLUETOOTH_NAME_PREFIX)调用会返回Boolean?(因为如果nullcontrollerId,它将返回null),这不能传递给&& Boolean运算符,只有真正的null可以。

此处的解决方案是对您在原始方法中执行的controllerId检查,并依靠将String投射到fun parseValidBluetoothBrickedId(controllerId: String?): Boolean = controllerId != null && controllerId.length > BLUETOOTH_NAME_PREFIX.length && controllerId.startsWith(BLUETOOTH_NAME_PREFIX) 的智能广播来摆脱安全通话:

#include <iostream>
using namespace std;
int main(){
    char *arr=new char;
    arr="monday";
    cout<<arr<<endl;//gives the output "monday"

    char *newArr=new char[3];//i want array of three pointers not the size of a string to be 2+1
    newArr[0]="monday";//err
    cout<<newArr[0]<<endl;


    system("pause");
    return 0;

}

答案 1 :(得分:2)

当您执行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

答案 2 :(得分:1)

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

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

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