当Kotlin函数不采用可空类型

时间:2017-06-27 16:21:00

标签: 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)

它有效,但感觉这不是正确的方法。还有更好的方法吗?

5 个答案:

答案 0 :(得分:2)

你可以做到

val a: Int? = 1
val b: Int? = 2
b?.let {
   a?.compareTo(b)
}
仅当b不为空时才会执行

let块。

或者只是

if (a != null && b != null) {
   a.compareTo(b)
}

我认为第二种解决方案非常清晰易读。

答案 1 :(得分:0)

没有为可空参数定义Int.compareTo()方法的签名,因此如果不通过例如确保参数的空安全性,则不可能做到这一点。像你建议的那样使用elvis操作符。

答案 2 :(得分:0)

您应该尝试在没有可空性的情况下实施您的解决方案。但是,如果您仍然需要它,并且假设null==0您不应该使用?.方法调用。它也会返回Int?。只需将null个整数映射到0。

(a?:0).compareTo(b?:0)

答案 3 :(得分:0)

唯一更好的方法是自己实施compareTo。当您将12nullnullnull进行比较时,默认比较不知道您想要的结果。它只知道如何比较实际数字。我认为您最好的方法是实现处理null s。

所需的行为

示例实施:

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)
}

答案 4 :(得分:-1)

表达式应该是这样的:

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

IF 您希望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;