【问题标题】:type inference failed in Kotlin funKotlin fun 中的类型推断失败
【发布时间】:2019-04-29 15:26:28
【问题描述】:

将 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 函数一直说“错误:(29, 21) Kotlin:类型推断失败。预期的类型不匹配:推断的类型是成分?但成分是预期的”。委托函数 mapRowToIngredient(rs: ResultSet, rowNum: Int ): 成分返回的是成分,而不是成分?

有什么想法吗?

  1. 列表项

【问题讨论】:

    标签: kotlin mismatch


    【解决方案1】:

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

    如果queryForObject返回null,那么你提供的映射器函数将被省略,最终函数会返回null

    可以使findById 函数返回可空类型(更改声明以使其返回Ingredient?),如果queryForObject 返回null(例如jdbc.queryForObject(...) ?: DEFAULT_RESPONSE),则指定要返回的默认对象) 或对非空类型使用强制“拆箱”(例如jdbc.queryForObject(...)!!)。

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

    【讨论】:

    • 感谢您的帮助。我以为JdbcTemplate返回Null时注解@Throw会处理异常,所以我不需要自己处理。
    猜你喜欢
    • 2018-08-21
    • 2020-12-30
    • 2018-05-15
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 2020-03-31
    相关资源
    最近更新 更多