我就是无法用Java思维理解Groovy类型

uplii1fm  于 2022-12-11  发布在  Java
关注(0)|答案(1)|浏览(137)

我很难理解为什么在Java中可以工作的代码,在Groovy中却失败了。例如:
我发现如果我使用Tuple2.of(...,我会得到一个编译错误,但是new Tuple2(..可以工作。为什么?

static Stream<Tuple2<LocalDate, Double>> forecastEachMonth(Tuple2<LocalDate, Double> openingBalance, Double rate){

        Stream<Tuple2<LocalDate, Double>> stream = Stream.iterate(
                openingBalance,
                {

                    LocalDate current = it.first
                    LocalDate nextDate = it.first.plusMonths(1)

                    int days = Days.daysBetween(current, nextDate).days
                    double years = days / 365.0
                    double interest = it.second * rate * years
                    double nextBalance = it.second + interest

                    // return Tuple2.of(nextDate, nextBalance) // exception after 2 iterations, Have no idea why.
                    return new Tuple2(nextDate, nextBalance)
                }
        )
        return stream
    }

您可以对此进行测试:

Stream<Tuple2<LocalDate,Double>> test = forecastEachMonth(
                        LocalDate.now(),
                        200000.0d,
                0.05d
        )
        println test.limit(200).collect(Collectors.toList())

给出错误:

Expected earlier checking to detect generics parameter arity mismatch
Expected: groovy.lang.Tuple<E> 
Supplied: groovy.lang.Tuple<org.joda.time.LocalDate,java.lang.Double>

但是当我将鼠标悬停在局部变量上时,Intellij知道正确的类型。
我还把这个项目转换成了Java,而且它还能正常工作,这严重影响了我在Groovy中的编程经验,因为我浪费了大量的时间在那些能用Java编写但不能用Groovy编写的代码上。(虽然Java中没有Tuple,但我只是使用了另一个具有集合Pair的库)。但我就是不明白为什么Groovy突然不知道给定变量的类型,然后抛出一个异常,这有什么可取之处呢

gzjq41n4

gzjq41n41#

我无法理解你“java”的痛苦。
以下代码示例即使在编译静态时也能很好地工作:

@groovy.transform.CompileStatic
def f(){
  Tuple2<Date, Double> a = new Tuple2(new Date(), 1)
  Tuple2<Date, Double> b = new Tuple2(new Date(), 2)

  List<Tuple2<Date, Double>> list = [a,b]
  List<Tuple2<Date, Double>> result = list.takeWhile{Tuple2<Date, Double> e-> e.getV2()<2}

  assert result instanceof List
  assert result.size()==1
  assert result[0].getV2()<2
  assert result[0] instanceof Tuple2
}

f()

您的问题:

我发现如果我使用Tuple2.of(...,我会得到一个编译错误,但是new Tuple2(..可以工作。为什么?
Tuple2 class中没有这样的方法Tuple2.of(...
为什么Groovy突然不知道一个给定变量的类型,恢复为Object,然后抛出一个异常,这有什么可取之处呢?
我用你的代码与最小的变化,使它可运行,它的工作没有任何错误:

import java.time.*
import java.util.stream.*

static Stream<Tuple2<LocalDate, Double>> forecastEachMonth(Tuple2<LocalDate, Double> openingBalance, Double rate){

    Stream<Tuple2<LocalDate, Double>> stream = Stream.iterate(
            openingBalance,
            {

                LocalDate current = it.first
                LocalDate nextDate = it.first.plusMonths(1)

                int days = nextDate - current
                double years = days / 365.0
                double interest = it.second * rate * years
                double nextBalance = it.second + interest

                return new Tuple2(nextDate, nextBalance)
            }
    )
    return stream
}

Stream<Tuple2<LocalDate,Double>> test = forecastEachMonth(
    new Tuple2(LocalDate.now(),200000.0d),
    0.05d
)
println test.limit(200).collect(Collectors.toList())

相关问题