将springboot java演示转换为kotlin演示,并遇到类型推断失败的问题。
取回目标结果很有趣
package tacocloud.data
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Repository
import tacocloud.Ingredient
import tacocloud.Type
import java.sql.ResultSet
import java.sql.SQLException
@Repository
class JdbcIngredientRepository
@Autowired
constructor( private val jdbc: JdbcTemplate) : IngredientRepository {
override fun findAll(): Iterable<Ingredient> {
return jdbc.query("select id, name, type from Ingredient"
) { rs, rowNum -> this.mapRowToIngredient(rs, rowNum) }
}
override fun findById(id: String): Ingredient {
return jdbc.queryForObject(
"select id, name, type from Ingredient where id=?",
{ rs, rowNum -> mapRowToIngredient(rs, rowNum)}, arrayOf(id))
}
@Throws(SQLException::class)
private fun mapRowToIngredient(rs: ResultSet, rowNum: Int): Ingredient {
return Ingredient(
rs.getString("id"),
rs.getString("name"),
Type.valueOf(rs.getString("type")))
}
override fun save(ingredient: Ingredient): Ingredient {
jdbc.update(
"insert into Ingredient (id, name, type) values (?, ?, ?)",
ingredient.id,
ingredient.name,
ingredient.type.toString())
return ingredient
}
}
findById函数一直说:“错误:(29,21)Kotlin:类型推断失败。预期的类型不匹配:推断的类型是成分?但是预期成分”。委托函数mapRowToIngredient(rs:ResultSet,rowNum:Int ):配料返回了配料,而不是配料?
有什么想法吗?
答案 0 :(得分:1)
JdbcTemplate
是从Java源代码文件编译的,在Java中,任何引用都可以指向null
。这就是queryForObject
返回可为null的类型的原因-Kotlin倾向于将所有Java引用的返回声明视为可为null(有关更多信息,请参阅“ platform types”)。
如果queryForObject
返回null
,则您提供的映射器函数将被省略,并且null
最终将从函数中返回。
可以使findById
函数返回可为null的类型(更改声明,使其返回Ingredient?
),如果queryForObject
返回了{{ 1}}(例如null
)或对非null类型使用“拆箱”力(例如jdbc.queryForObject(...) ?: DEFAULT_RESPONSE
)。
PS:通过id查询得到空响应是很常见的(例如,删除了这个id的项等等),并且在这种情况下,存储库通常返回可为null的类型或引发异常,因此我个人会坚持使用此解决方案。但是,如果您的设计保证在通过id查询时项始终存在,那么我将使用jdbc.queryForObject(...)!!
强制将可空类型强制转换为不可空类型。