вывод типа не удалось в Kotlin весело - PullRequest
0 голосов
/ 29 апреля 2019

переведите демонстрационную версию Java Springboot в 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 Ответ

1 голос
/ 29 апреля 2019

JdbcTemplate, я полагаю, компилируется из файла исходного кода Java, и в Java любая ссылка может указывать на null.Вот почему queryForObject возвращает обнуляемый тип - Kotlin имеет тенденцию считать все декларации возврата ссылок Java обнуляемыми (для получения дополнительной информации обратитесь к " типам платформ ").

И если queryForObject возвращает null, тогда предоставленная вами функция отображения будет просто опущена, и null будет возвращено из функции в конечном итоге.

Можно сделать так, чтобы findById функция возвращала тип, допускающий значение NULL (изменитьобъявление так, чтобы оно возвращало Ingredient?), укажите объект по умолчанию для возврата, если queryForObject вернул null (например, jdbc.queryForObject(...) ?: DEFAULT_RESPONSE), или используйте силу "unboxing" для ненулевого типа (например, * 1018)*).

PS: довольно часто можно получить пустой ответ с помощью запроса идентификатора (например, элемент с этим идентификатором был удален или около того), и хранилища часто возвращают обнуляемый тип или выдают исключение в таком случае,так что лично я бы придерживался этого решения.Но если ваш дизайн гарантирует, что элемент всегда будет присутствовать при запросе по id, я бы использовал !!, чтобы привести тип NULL к NULL в силу.

...