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?
(因为如果controllerId
为null
,它将返回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?
。 你不能比较Int
与Int?
。 这就是你得到第一个错误的原因。
你得到另一个错误,因为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