Kotlin-扩展功能和平台类型?

我想将两个扩展函数添加到ResultSet ,获得一个LocalDate值。

 fun ResultSet.getLocalDate(colName: String) = getDate(colName)?.toLocalDate() fun ResultSet.getLocalDate(colIndex: Int) = getDate(colIndex)?.toLocalDate() 

问题是getDate()返回一个Date! ,显然我可以得到一个空错误没有?.toLocalDate()之前调用。 但是,那么使用这个扩展的任何人都必须使用结果作为LocalDate? 而不是LocalDate!

为了一致性,有没有办法维护平台类型? 让扩展函数的用户决定是否允许为空? 或者,我认为这是一个不便,而不是一个功能?

从另一个角度来看它:如果你可以让你的函数返回平台类型LocalDate!的值LocalDate! ,Java不安全性可能会扩展到Kotlin代码中的函数用法:它们会在任何时候返回null ,这对调用者来说可能是意外的,使用返回值非空。

反过来,Kotlin 是无效的 ,它不允许将null静静地传递到某个会导致NPE的地方。 相反,每个值都可以为空或传递非空的检查或断言。

平台类型在语言中是不可指定的,这只是一种处理不安全的Java可空性的方法(简单地把所有的Java值视为可为空都不行 )。 他们为您提供了一种方式来表明您相信对Java代码的这种调用不会返回null :当您对待T! 作为T ,产生一个断言来检查它。 否则,你使用平台类型T! 如可空T?

空值安全是Kotlin语言设计的关键之一,它使您可以决定Kotlin代码中的每个值是否为空。

您有两个API设计选项:

  • 返回一个非空值,检查函数内部的可空性
  • 返回可为空的值,从而警告调用者可能的null

但是,如果一个函数具有允许调用者假设它在某些条件下不会返回null语义,那么可以创建一个包装函数来进行断言。 这是可行的,如果再加上逻辑或回退,否则它几乎不会比呼叫站点断言( !! )更简洁。