Kotlin乐趣中类型推断失败

时间:2019-04-29 15:26:28

标签: kotlin mismatch

将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 ):配料返回了配料,而不是配料?

有什么想法吗?

  1. 列表项

1 个答案:

答案 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(...)!!强制将可空类型强制转换为不可空类型。