我有一个简单的功能检查,如下所示:
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 回答
你不能在
controllerId?.length
上调用compareTo
(使用<
运算符),因为它的类型是Int?
,这意味着它可能是null
,在这种情况下它不能作为数字进行比较 .类似地,
controllerId?.startsWith(BLUETOOTH_NAME_PREFIX)
调用返回Boolean?
(因为它将返回null
,如果controllerId
是null
),它不能传递给&&
运算符,只能返回真正的Boolean
.这里的解决方案是使用原始方法执行
null
检查,并依靠智能转换将controllerId
转换为String
来摆脱安全调用:当你做
controllerId?.length
时,你得到一个Int?
. 您无法将Int
与Int?
进行比较 . 这就是你得到第一个错误的原因 .您收到另一个错误,因为
controllerId?.startsWith(BLUETOOTH_NAME_PREFIX)
返回Boolean?
. 您不能在可以为null的参数上使用&&
运算符 . 它需要两个类型为Boolean
的参数 .要解决这些问题,首先需要检查
controllerId != null
. 这将智能转换controllerId
为非可空类型String
. 像这样:您转换的函数缺少
null
检查:与第一个示例一样,编译器必须进行空检查才能知道
controllerId
不是null
. 检查后,编译器使用"smart casting"并且调用是安全的 . 因此,检查后您不必使用?.
表示法 .