Kotlin推断JOOQ方法错误

编程入门 行业动态 更新时间:2024-10-26 00:26:37
本文介绍了Kotlin推断JOOQ方法错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

给定使用Kotlin版本1.3.61和JOOQ版本3.13.1的系统,像这样的方法通常会构建union查询:

Given a system using Kotlin version 1.3.61 and JOOQ version 3.13.1, a method like this builds an union query normally:

val selectCommonPart = coalesce(sum(field(name("amount"), Long::class.java)), ZERO) .`as`(field(name("totalAmount"))) var whereCommonPart: Condition = trueCondition().and(field(name("Id")).eq(Id)) // Id comes as a parameter var query = dsl.selectQuery() query.addSelect(selectCommonPart) query.addFrom(table("${tableName(startDate)}")) // `startDate` is a `LocalDate`, `tableName()` generates the table name as String query.addConditions(whereCommonPart) // `endDate` is also a `LocalDate`, can be either equal to `startDate` or after if (endDate.isAfter(startDate)) { for (date in Stream.iterate(startDate.plusDays(1), { d: LocalDate -> d.plusDays(1) }) .limit(ChronoUnit.DAYS.between(startDate, endDate)) .collect(Collectors.toList())) { val unionQuery = dsl.selectQuery() unionQuery.addSelect(selectCommonPart) unionQuery.addFrom(table("public.${tableName(date)}")) unionQuery.addConditions(whereCommonPart) // Here `union` is inferred correctly query.union(dsl.select(selectCommonPart) .from("public.public.${tableName(date)}") .where(whereCommonPart)) } }

但是,如果我用类似的方法隔离dsl.select(...)部分:

However, if I isolate the dsl.select(...) part in a method like:

private fun buildSelect(selectCommonPart: Field<*>, whereCommonPart: Condition, date: LocalDate): Select<*> { var query = dsl.selectQuery() query.addSelect(selectCommonPart) query.addFrom(table("public.${tableName(date)}")) query.addConditions(whereCommonPart) return query }

并修改循环以使用:

// Remove this part /* var query = dsl.selectQuery() query.addSelect(selectCommonPart) query.addFrom(table("${tableName(startDate)}")) // `startDate` is a `LocalDate`, `tableName()` generates the table name as String query.addConditions(whereCommonPart) */ // Add this part var query = buildSelect(selectCommonPart, whereCommonPart, startDate) if (endDate.isAfter(startDate)) { for (date in Stream.iterate(startDate.plusDays(1), { d: LocalDate -> d.plusDays(1) }) .limit(ChronoUnit.DAYS.between(startDate, endDate)) .collect(Collectors.toList())) { // This gives an inference error query.union(buildSelect(selectCommonPart, whereCommonPart, date)) } }

我有一个推断错误. Kotlin将union解析为这种方法:

I have an inference error. Kotlin resolves union as this method:

/** * Returns a set containing all distinct elements from both collections. * * The returned set preserves the element iteration order of the original collection. * Those elements of the [other] collection that are unique are iterated in the end * in the order of the [other] collection. * * To get a set containing all elements that are contained in both collections use [intersect]. */ public infix fun <T> Iterable<T>.union(other: Iterable<T>): Set<T> { val set = this.toMutableSet() set.addAll(other) return set }

我想改用JOOQ的Select<*>的union:

I want to use JOOQ's Select<*>'s union instead:

public interface Select<R extends Record> extends ResultQuery<R>, TableLike<R>, FieldLike { /** * Apply the <code>UNION</code> set operation. */ @Support Select<R> union(Select<? extends R> select);

我应该怎么做才能推断出正确的union方法?

What should I do to infer the correct union method?

推荐答案

好,我知道了如何解决您的问题.

Ok, I found out how to fix your issue.

方法 buildSelect 应该返回 Select<记录> ,而不是选择< *> .

Method buildSelect should returns Select< Record>, not Select< *>.

我的建议为什么会发生

Select.union方法具有以下签名

The Select.union method has the following signature

public interface Select<R extends Record> extends ResultQuery<R>, TableLike<R>, FieldLike { @Support Select<R> union(Select<? extends R> var1); ....

如您所见, var1 应该与调用方法的对象具有相同的泛型(或扩展)类型.在您的第一个实现中,方法 dsl.selectQuery()返回 SelectQuery< Record> 都是变量 query 和 unionQuery 具有相同的泛型类型,并且联合方法已正确确定.

As you can see, var1 should have the same generic( or extended) type as the object on which method was called. In your first implementation, method dsl.selectQuery() returns SelectQuery< Record> and both are variables query and unionQuery have the same generic type and the union method is correctly determined.

在第二种实现中, query 和 query.union(...)的参数具有 Select< *> 类型.我猜编译器认为两个变量具有不同的泛型(因为未确定并且可以不同),并且编译器不能使用Select中的并集,但是两个变量都实现了 Iterable ,并且编译器选择了 Iterable.union ,因为它合适.

In the second implementation, query and the argument of query.union(...) have Select< *> type. I guess that the compiler thinks that both variables have different generic(since it is not determined and can be different) and the compiler can't use union from Select, but both variables implement Iterable and compiler choose Iterable.union since it fits.

更多推荐

Kotlin推断JOOQ方法错误

本文发布于:2023-11-25 17:32:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1630690.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:推断   错误   方法   Kotlin   JOOQ

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!