Kotlin:不能同时应用两个条件检查“return body”函数样式

我有一个简单的函数检查是这样的:

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),并说:

类型不匹配。 必需:布尔值,找到布尔值?

什么问题,真的吗? 这只是一个简单的方法,适用于第一块if-else样式。

你不能在controllerId?.length调用compareTo (使用< operator),因为它的类型是Int? ,这意味着它可能是null ,在这种情况下,它不能被比作一个数字。

同样, controllerId?.startsWith(BLUETOOTH_NAME_PREFIX)调用返回Boolean? (因为如果controllerIdnull ,它将返回null ),它不能传递给&&操作符,只有一个真正的Boolean可以。

这里的解决方案是在原始方法中执行null检查,并通过依赖智能强制转换将您的controllerId转换为String来摆脱安全调用:

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

您的转换功能缺少null检查:

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

和你的第一个例子一样,编译器需要进行空检查,即controllerId不为null 。 检查后,编译器使用“智能铸造”和调用是安全的。 所以你不必使用?. 检查后的符号。

当你做controllerId?.length ,你得到一个Int? 。 你不能比较IntInt? 。 这就是你得到第一个错误的原因。

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

为了解决这个问题,你需要首先检查controllerId != null 。 这将智能强制controllerId转换为不可为空的类型的String 。 喜欢这个:

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