Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么queryForObject Kotlin扩展函数返回可为null的T?如果它真的抛出EmptyResultDataAccessException?_Kotlin_Spring Jdbc_Spring Kotlin - Fatal编程技术网

为什么queryForObject Kotlin扩展函数返回可为null的T?如果它真的抛出EmptyResultDataAccessException?

为什么queryForObject Kotlin扩展函数返回可为null的T?如果它真的抛出EmptyResultDataAccessException?,kotlin,spring-jdbc,spring-kotlin,Kotlin,Spring Jdbc,Spring Kotlin,在一些简单的项目中使用Kotlin和Spring5。 我想使用queryForObject从数据库中按id获取单个记录。 我的查询是“简单的按id选择”: jdbc.queryForObject("select id, name from example where id = ?", id) { rs: ResultSet, _: Int -> NamedEnt(rs.getLong("id"), rs.getString("name") } 在JdbcOperationsExtensi

在一些简单的项目中使用Kotlin和Spring5。 我想使用
queryForObject
从数据库中按id获取单个记录。 我的查询是“简单的按id选择”:

jdbc.queryForObject("select id, name from example where id = ?", id)
{ rs: ResultSet, _: Int -> NamedEnt(rs.getLong("id"), rs.getString("name") }
JdbcOperationsExtensions.kt
中,声明返回可为空的类型
T?

fun <T : Any> JdbcOperations.queryForObject(sql: String, vararg args: Any, function: (ResultSet, Int) -> T): T? =
    queryForObject(sql, RowMapper { resultSet, i -> function(resultSet, i) }, *args)
queryForObject(sql:String,vararg-args:Any,function:(ResultSet,Int)->T):T= queryForObject(sql,行映射程序{resultSet,i->function(resultSet,i)},*args) 实际上,当我传递不存在的标识符时,我会面临:

org.springframework.dao.EmptyResultDataAccessException:结果大小不正确:应为1,实际为0


那么我不明白返回可为null的类型有什么意义?您要么收到一条记录,要么收到一个异常。或者我错过了什么?

JdbcOperationsExtensions.kt
org.springframework.jdbc.core.JdbcOperations
接口(用Java编写)添加了一些扩展函数。如果你看一下JavaDocs中的
queryForObject
,它会说:

@return the single mapped object (may be {@code null} if the given
{@link RowMapper} returned {@code} null)
有关
JdbcOperations
Java类的完整源代码,请参阅


因此,Kotlin编写的扩展函数需要遵循这一点,并允许返回null,从而得到可为null的类型

除了。。。正如@AlexeyRomanov所指出的,
queryForObject
的这个特殊重载包含一个lambda,它返回
T
,因此永远不能返回null,因此可以说这个重载可以返回
T
,而不是
T?
。Kotlin中的lambda不能返回null可能有点不一致,但是Java类中非常相似的重载上的JavaDocs明确声明应该允许它(
RowMapper
)返回null


不管这一点如何,其他一些
queryForObject
重载只是调用Java编写的重载,因为它是用Java编写的,所以它可能返回null。因此,对于他们来说,将其作为可为空的返回值似乎是有意义的。在这种情况下,所有重载实际上都返回可为null的
T

“因此Kotlin编写的扩展函数需要遵守这一点,并允许返回null”,但它们不这样做:
函数:(ResultSet,Int)->T
不能返回
null
,因此使用它的
行映射器
不能返回
null
.Ha!阿列克谢罗曼诺夫:我错过了。我想知道这是否是扩展方法中的一个小错误:可能传递到
queryForObject
的lambda应该声明为具有
T?
的返回类型。因为JavaDocs似乎建议应该允许
行映射器
返回null.Agreed。问题已记录。@AlexeyRomanov您能详细说明一下为什么这些扩展应该是内联的吗?表演?是的。胜利并没有那么大,尤其是与数据库访问相比,但在我看来,您需要一个不将此类方法声明为内联的理由(例如)。也许这件事有这样的原因,我只是不明白。