Kotlin- 扩展函数和平台类型?

3

我想要为ResultSet添加两个扩展函数,用于获取值作为LocalDate

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

问题是getDate()返回一个Date!,如果没有在toLocalDate()之前使用?.调用,显然我可能会出现空值错误。但是,这样一来,任何使用此扩展的人都必须将结果用作LocalDate?而不是LocalDate!
有没有办法为了保持一致性而保留平台类型?并让扩展函数的用户决定是否允许为空?或者我是将其视为不便而不是功能吗?

1
我猜这引出了一个更大的设计问题:如果JDBC是用Kotlin编写的,那么每个字段getter都将是可空的吗?这可能是有道理的,因为库不知道表中的列是否可为空... - tmn
1个回答

4
从另一个角度来看:如果您可以使函数返回平台类型LocalDate!的值,Java不安全的空值性将传播到您的Kotlin代码中使用该函数的地方:它们可能随时返回null,这可能会令调用者使用非空返回值时感到意外。
反过来,Kotlin 是空值安全的,它不会默默地将null传递到可能导致NPE的位置。相反,每个值都以可为空或非空检查或断言的方式传递。 平台类型在语言中是不可表示的,这只是一种处理不安全的Java空值性的方法(简单地将所有Java值视为可空的不起作用)。它们为您提供了一种声明您相信此调用Java代码不会返回null的方式:当您将T!视为T时,将生成断言来检查它。否则,您将像处理可空的T?一样使用平台类型T!
空值安全是Kotlin语言设计的关键点之一,它使您决定Kotlin代码中每个值是否可空。
对于API设计,您有两个选项:
  • 返回非空值,并在函数内部检查其空值性
  • 返回可空值,从而警告调用者可能会出现null
但是,如果函数具有允许调用者假定它在某些条件下不会返回null的语义,则可以创建一个包装器函数来进行断言。如果与其他逻辑或回退耦合,这是可行的,否则它几乎不会比调用站点上的断言()更简洁。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接