当Kotlin函数不采用nullable类型时,正确的方法是什么

当Kotlin函数不采用nullable类型时,正确的方法是什么,kotlin,Kotlin,所以我在解决Koans问题时,通过我过于复杂的解决方案,遇到了一件困扰我的事情。我在可空类型上使用Int.compareTo()函数。如果第一个可以为null,那么这很“容易”,因为我只写了: val a : Int? = 1 val b : Int = 1 a?.compareTo(b) 但是如果b是可空的,那么我就不能让它工作,也许我遗漏了什么?那么在这种情况下该怎么办呢 val a : Int? = 1 val b : Int? = 2 a?.compareTo(b) 我收到一个语法错

所以我在解决Koans问题时,通过我过于复杂的解决方案,遇到了一件困扰我的事情。我在可空类型上使用Int.compareTo()函数。如果第一个可以为null,那么这很“容易”,因为我只写了:

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)

这是可行的,但感觉这不是正确的方法。有更好的方法吗?

Int.compareTo()方法的签名不是为可为空的参数定义的,因此如果不确保参数的空安全性,就不可能做到,例如,按照您的建议使用elvis运算符。

您应该尝试在不可为空的情况下实现您的解决方案。但是,如果您仍然需要它,并且可以安全地假设
null==0
,则不应该使用
?。
方法调用。它还将返回一个
Int?
。只需将两个
null
整数映射为0

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

唯一更好的方法是实现
compareTo
自己。当您将
12
null
null
null
进行比较时,默认比较不知道您想要什么结果。它只知道如何比较实际数字。我认为最好的方法是实现处理
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)
}
fun main(args:Array){
println(compareNullableInts(null,2))/-1
println(compareNullableInts(null,null))//0
println(compareNullableInts(2,null))//1
println(compareNullableInts(10,5))//1
}
有趣的比较整数(a:Int?,b:Int?:Int){
如果(a==null&&b==null)返回0
if(a==null)返回-1
如果(b==null)返回1
返回a.compareTo(b)
}

表达式应如下所示:

val result = b?.let { a?.compareTo(b) ?: -1 } ?: 1;
例子 如果希望让
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;
你能行

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

或者只是

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

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

您需要定义“工作”。null与42相比应该是什么?42与null相比应该是什么?空与空相比应该是什么?您需要定义“工作”。null与42相比应该是什么?42与null相比应该是什么?空与空的比较应该是什么?比较可空原语通常相当复杂。在这些情况下,使用默认的
compareTo
实现只有以您已经展示的方式才能真正实现。首先要确定的是,您希望与
null
值进行比较的结果是什么,然后您可以编写自己的解决方案来进行比较。我同意很难将null值与现有值进行比较,但假设我正在试图找到一种方法来比较Kotlin中不存在的原语,因为一切都是一个对象。例如,我相信Python会将所有内容都视为对象,但(5<4)=True是存在的。我意识到上述情况并非如此,在某种程度上存在原语,当它不是可为null的对象时,可以对其进行比较。主席先生,表达式
(null?:0)。compareTo(-1)
违反了规则。它返回一个正数
1
。。。。这意味着
null
大于
-1
,如果您假设
null
等于
0
,那么这就是您所期望的。
if (a != null && b != null) {
   a.compareTo(b)
}