gpt4 book ai didi

java - 为什么这不会重载?

转载 作者:搜寻专家 更新时间:2023-11-01 03:45:52 25 4
gpt4 key购买 nike

写在 Jooq 助手类上。 (一旦我弄明白了,就会添加更多特定于业务的方法...)

import org.jooq.*
import org.springframework.stereotype.Repository
import javax.inject.Inject
import javax.inject.Provider

/**A helper class facilitating database manipulations.
* Uses jOOQ for its manipulations.
* Relies on the application context being properly initialized s.t. Spring creates and injects the correct
* [DSLContext].*/
@Repository
class DatabaseManipulator{

private val provider: Provider<DSLContext>
private val create:DSLContext
get() = provider.get()

@Inject
constructor(provider: Provider<DSLContext>) {
this.provider = provider
}


/**Executes non-[Select]-type SQL queries on the database.
* Does not perform any kind of checks and trusts the client to know what they're doing.
* @param query the query to be executed.
*
* @return depending on the type of the [query]:
* <ul>
* <li> Delete : the number of deleted records</li>
* <li> Insert : the number of inserted records</li>
* <li> Merge : result may be meaningless</li>
* <li> Truncate : result may be meaningless</li>
* <li> Update : the number of updated records</li>
* </ul>
*/
fun execute(query:DSLContext.()-> Query):Int{
return create.query().execute()
}

/**Executes [Select]-type [query] and returns its result*/
fun <T:Record> execute(query:DSLContext.()->Select<T>):Result<T>{
return create.query().fetch()
}
}

到目前为止,还不错。现在让我们添加一些测试

@RunWith(SpringJUnit4ClassRunner::class)
@SpringBootTest
@Transactional
class DatabaseManipulatorIT {

@Inject
private lateinit var manipulate:DatabaseManipulator

@Inject
private lateinit var em:EntityManager

@Test
fun executeSelectQuery() {
//given
val expectedNumberOfOrganizations = em.createQuery("SELECT COUNT (o) FROM Organization o")
.singleResult as Long

//when
val reportedNumberOfOrganizations = manipulate.execute {
selectCount().from(ORGANIZATION)
}.first().value1().toLong()

//then
assertThat(reportedNumberOfOrganizations).isEqualTo(expectedNumberOfOrganizations)
}

@Test
fun executeNonSelectQuery() {
//given
val expectedNumberOfDeletions = em.createQuery(
"SELECT COUNT (o) FROM Organization o WHERE o.usageCreditLimited = true"
).singleResult as Long

//when
val actualNumberOfDeletions = manipulate.execute {(
deleteFrom(ORGANIZATION)
.where(ORGANIZATION.USAGECREDITLIMITED.eq(true))
) as Query
}

//then
assertThat(actualNumberOfDeletions).isEqualTo(expectedNumberOfDeletions)

}
}

编译失败是因为

Error:(50, 50) Kotlin: Type inference failed: fun <T : Record> execute(query: DSLContext.() -> Select<T>): Result<T>
cannot be applied to
(DSLContext.() -> DeleteConditionStep<OrganizationRecord!>!)
Error:(50, 58) Kotlin: Type mismatch: inferred type is DSLContext.() -> DeleteConditionStep<OrganizationRecord!>! but DSLContext.() -> Select<???> was expected

不废话,我不想你用那个方法,我想让你用其他

让我们试着明确一点:

//when
val actualNumberOfDeletions = manipulate.execute {(
deleteFrom(ORGANIZATION)
.where(ORGANIZATION.USAGECREDITLIMITED.eq(true))
) as Query
}

仍然无法编译第二个测试用例,因为

Error:(50, 50) Kotlin: Type inference failed: fun <T : Record> execute(query: DSLContext.() -> Select<T>): Result<T>
cannot be applied to
(DSLContext.() -> Query)
Error:(50, 58) Kotlin: Type mismatch: inferred type is DSLContext.() -> Query but DSLContext.() -> Select<???> was expected

如何让 Kotlin 调用正确的方法?

最佳答案

Select 本质上是 Query,因此无法正确推断您要使用的方法。

The compiler resolves everything about the method invocation without paying any attention to the generic constraints involved until the very last moment – where it notices that the chosen method isn’t valid, and fails with an error.

generics 会出现此问题,编译器将这些方法识别为两种不同的方法,但在尝试解析该方法时,它可能无法根据可用数据找到正确的方法。如果您想知道为什么查看这篇文章,Overloading and Generic constraints乔恩·斯基特 (Jon Skeet) 着。

关于java - 为什么这不会重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55829074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com