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 一种成分,而不是一种成分?
有什么想法吗?
- 列表项
我想 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 查询时始终存在某个项目,我会使用 !!
强制将可空类型强制转换为不可空类型。
将一个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 一种成分,而不是一种成分?
有什么想法吗?
- 列表项
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 查询时始终存在某个项目,我会使用 !!
强制将可空类型强制转换为不可空类型。