Kotlin 如何避免!!在返回不可为null的

Kotlin 如何避免!!在返回不可为null的,kotlin,nullable,Kotlin,Nullable,在下面的示例中,函数应该返回非null数据。 由于数据可以在流程中更改,因此它需要是var,并且只能在开始时为null 我不能使用lateinit,因为if(d==null)的第一个调用将抛出 处理后,它将被分配一个非空数据,但返回必须使用(双关或非空断言运算符) 避免的最佳方法是什么 fun testGetLowest (dataArray: List<Data>) : Data { var d: Data? = null for (i in dataArray.ind

在下面的示例中,函数应该返回非null数据。 由于数据可以在流程中更改,因此它需要是var,并且只能在开始时为null

我不能使用
lateinit
,因为
if(d==null)
的第一个调用将抛出

处理后,它将被分配一个非空数据,但返回必须使用
(双关或非空断言运算符)

避免
的最佳方法是什么

fun testGetLowest (dataArray: List<Data>) : Data {
   var d: Data? = null
   for (i in dataArray.indecs) {

       if (d == null) {// first run
           d = dataArray[i]
       } else if {
           d.level < dataArray[i].level
           d = dataArray[i]
       }
    }
    return d!!
}
fun testgetlower(dataArray:List):数据{
变量d:数据?=null
对于(dataArray.indecs中的i){
如果(d==null){//第一次运行
d=数据阵列[i]
}否则如果{
d、 级别<数据数组[i]。级别
d=数据阵列[i]
}
}
返回d!!
}
如何进行同样的检查,并覆盖空箱子
fun testgetlower(dataArray:List)
=dataArray.minBy{it.level}?:抛出断言错误(“列表为空”)
这将使用
?:
运算符获取最小值,或者如果最小值为null(列表为空),则会抛出一个错误。

如何执行相同的检查,并覆盖空的大小写
fun testgetlower(dataArray:List)
=dataArray.minBy{it.level}?:抛出断言错误(“列表为空”)

这将使用
?:
运算符获取最小值,或者如果最小值为null(列表为空),则会抛出一个错误。

即使要将其转换为
选项
,也必须处理
数据数组
为空且返回值未定义的情况


如果您想使其成为一个完整的函数,而不是引发异常,您可以返回一个
选项
而不是
数据
,这样空的
数据数组
将返回一个
,并让调用者自行处理sad路径。

即使您要将其转换为
选项
,您仍然需要处理
dataArray
为空,因此返回的值未定义的情况


如果您想使这成为一个完整的函数而不是抛出异常,您可以返回一个
选项而不是
数据
,这样空
数据数组
的情况将返回一个
,并让调用者处理sad路径。

如果您不喜欢
然后为其提供默认值。您将认识到,只有当列表不是空的时候,您才能提供默认值,但是,正如您所说,列表已经被认为是非空的。这个故事的好处在于类型系统不跟踪列表大小,所以当你说
dataArray[0]
时,它会相信你的话

fun testGetLowest(dataArray: List<Data>) : Data {
    var d: Data = dataArray[0]
    for (i in 1 until dataArray.size) {
        if (d.level < dataArray[i].level) {
            d = dataArray[i]
        }
    }
    return d
}
fun testgetlower(dataArray:List):数据{
变量d:Data=dataArray[0]
for(在dataArray.size之前的1中的i){
if(d.level
如果你不喜欢
然后为其提供默认值。您将认识到,只有当列表不是空的时候,您才能提供默认值,但是,正如您所说,列表已经被认为是非空的。这个故事的好处在于类型系统不跟踪列表大小,所以当你说
dataArray[0]
时,它会相信你的话

fun testGetLowest(dataArray: List<Data>) : Data {
    var d: Data = dataArray[0]
    for (i in 1 until dataArray.size) {
        if (d.level < dataArray[i].level) {
            d = dataArray[i]
        }
    }
    return d
}
fun testgetlower(dataArray:List):数据{
变量d:Data=dataArray[0]
for(在dataArray.size之前的1中的i){
if(d.level
通常,您可以而且应该依靠编译器来推断可空性。这并不总是可能的,在人为的示例中,如果内部循环只运行一次
d
则为非空。如果
dataArray
至少有一个成员,则肯定会发生这种情况

利用这些知识,您可以使用检查参数(至少一个数组成员)和断言
dataArray
的状态作为post条件来稍微重构代码

fun testGetLowest (dataArray: List<Data>) : Data {
   require(dataArray.size > 0, { "Expected dataArray to have size of at least 1: $dataArray")
   var d: Data? = null
   for (i in dataArray.indecs) {

       if (d == null) {// first run
           d = dataArray[i]
       } else if {
           d.level < dataArray[i].level
           d = dataArray[i]
       }
    }
    return checkNotNull(d, { "Expected d to be non-null through dataArray having at least one element and d being assigned in first iteration of loop" })
}

有关类似的内容,请参见谷歌番石榴。

通常,您可以而且应该依靠编译器来推断可空性。这并不总是可能的,在人为的示例中,如果内部循环只运行一次
d
则为非空。如果
dataArray
至少有一个成员,则肯定会发生这种情况

利用这些知识,您可以使用检查参数(至少一个数组成员)和断言
dataArray
的状态作为post条件来稍微重构代码

fun testGetLowest (dataArray: List<Data>) : Data {
   require(dataArray.size > 0, { "Expected dataArray to have size of at least 1: $dataArray")
   var d: Data? = null
   for (i in dataArray.indecs) {

       if (d == null) {// first run
           d = dataArray[i]
       } else if {
           d.level < dataArray[i].level
           d = dataArray[i]
       }
    }
    return checkNotNull(d, { "Expected d to be non-null through dataArray having at least one element and d being assigned in first iteration of loop" })
}

有关类似的内容,请参见Google Guava。

公认的答案完全正确,但仅提及通过更改代码中的一行来解决问题的另一种方法:
返回d?:dataArray[0]

被接受的答案非常好,但仅提及通过更改代码中的一行来解决问题的另一种方法:
return d?:dataArray[0]

如果提供的列表为空怎么办?整个函数可以替换为
return dataArray.minBy{it.level}
。您仍然需要处理空列表案例。此示例用于显示“!!”问题,假设dataArray不是空的。类型系统没有假设任何内容,您是。所以不,
是通往go@yole,谢谢!示例可能被替换为
dataArray.minBy{it.level}
,但它试图在某些情况下显示它必须使用
var d:Data?
,然后它将强制使用“!!”稍后。如果提供的列表为空怎么办?整个函数可以替换为
return dataArray.minBy{it.level}
。您仍然需要处理空列表案例。此示例用于显示“!!”问题,假设dataArray不是空的。类型系统没有假设任何内容,您是。所以不,
是通往