当Kotlin函数不采用可空类型时,正确的方法是什么?
所以我正在解决Koans问题,通过我的过于复杂的解决方案碰到一个困扰我的东西。 我在可空类型上使用Int.compareTo()函数。 如果第一个是可空的,这是“容易的”,因为我只写:
val a : Int? = 1 val b : Int = 1 a?.compareTo(b)
但是,如果b是可以空的,那么我不能使它工作,也许我错过了什么地方? 那么在这种情况下该怎么办?
val a : Int? = 1 val b : Int? = 2 a?.compareTo(b)
我得到一个语法错误说:“下面的函数都不能用提供的参数调用。
但是,当我介绍这个:
val a : Int? = 1 val b : Int? = 2 val x : Int = b ?: 0; o1?.compareTo(x)
它的作品,但它感觉不是这样做的正确方法。 有没有更好的办法?
你可以做
val a: Int? = 1 val b: Int? = 2 b?.let { a?.compareTo(b) }
只有在b不为空的情况下,才会执行块。
要不就
if (a != null && b != null) { a.compareTo(b) }
我认为第二个解决方案非常清晰,易于阅读。
Int.compareTo()方法的签名没有为可为空的参数定义,所以不可能在没有确保参数的null安全性的情况下通过例如使用一个elvis操作符来完成,就像你所建议的一样。
你应该尝试实现你的解决方案,而不是可空的。 但是,如果你仍然需要它,如果可以安全地假设null==0
你不应该使用?.
方法调用。 它会返回给你一个Int?
以及。 只需将两个null
整数映射到0。
(a?:0).compareTo(b?:0)
唯一更好的方法是实现compareTo
自己。 默认的比较不知道你想要比较什么结果,即12
到null
或null
为null
。 它只知道如何比较实际的数字。 我认为你最好的方法是实现你想要处理null
的行为。
示例实现:
fun main(args: Array<String>) { println(compareNullableInts(null, 2)) // -1 println(compareNullableInts(null, null)) // 0 println(compareNullableInts(2, null)) // 1 println(compareNullableInts(10, 5)) // 1 } fun compareNullableInts(a: Int?, b: Int?): Int { if (a == null && b == null) return 0 if (a == null) return -1 if (b == null) return 1 return a.compareTo(b) }
表达应该是这样的:
val result = b?.let { a?.compareTo(b) ?: -1 } ?: 1;
例子
> a = 1 b = 2 ---> -1 > a = null b = 2 ---> -1 > a = null b = -1 ---> -1 > a = 1 b = null ---> 1 > a = -1 b = null ---> 1 > a = null b = null ---> 1 // the order is no matter
如果你想让null
比较null
返回0
那么表达式有点长:
val result = b?.let { a?.compareTo(b) ?: -1 } ?: a?.let { 1 } ?: 0;
注意 :你不关心性能,因为let
函数是一个内联函数。 这意味着它将在java中生成如下所示的代码:
int result = b != null ? a != null ? a.compareTo(b) : -1 : a != null ? 1 : 0;