Kotlin 乐趣中的类型推断失败

type inference failed in Kotlin fun

将一个springboot java demo 翻译成kotlin demo,运行 翻译成一个类型推断失败的问题。

获取目标结果是一个存储库乐趣

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 函数一直在说 "Error:(29, 21) Kotlin: Type inference failed. Expected type mismatch: inferred type is Ingredient? but Ingredient was expected"。委托函数 mapRowToIngredient(rs: ResultSet, rowNum: Int): Ingredient 有 return 一种成分,而不是一种成分?

有什么想法吗?

  1. 列表项
我想

JdbcTemplate 是从 Java 源代码文件编译而来的,在 Java 中任何引用都可以指向 null。这就是为什么 queryForObject return 是可空类型 - Kotlin 倾向于将所有 Java 的引用 return 声明视为可空(请参阅“platform types”了解更多信息信息)。

并且如果 queryForObject returns null,那么您提供的映射器函数将被省略并且 null 将从 returned最终发挥作用。

可以使 findById 函数 return 为可空类型(更改声明使其 return 成为 Ingredient?),指定默认对象到 return if queryForObject returned null(例如 jdbc.queryForObject(...) ?: DEFAULT_RESPONSE)或使用强制 "unboxing" 到非空类型(例如 jdbc.queryForObject(...)!!).

P.S.: 通过 id 查询得到一个空响应是很常见的(例如,这个 id 的项目被删除左右)并且存储库通常 return 可为空类型或抛出异常在这种情况下,我个人会坚持使用这个解决方案。但是,如果您的设计保证在按 id 查询时始终存在某个项目,我会使用 !! 强制将可空类型强制转换为不可空类型。