多种类型时的Scala方差

时间:2019-03-17 20:34:04

标签: scala generics apache-flink

通过这个答案https://stackoverflow.com/a/1759565/11217621,我知道在Java中可以做类似的事情

public class MyClass<S, T> {
   public        void foo(Set<S> s, Set<T> t); //same type params as on class
   public <U, V> void bar(Set<U> s, Set<V> t); //type params independent of class
}

其中<U, V>方法的bar与类参数类型无关。

我有一个像Java这样的简单数据类

public class DataPoint<T> {

    public long timeStampMs;
    public T value;

    public <R> DataPoint<R> withNewValue(R newValue){
        return new DataPoint(this.timeStampMs, newValue);
    }

    public KeyedDataPoint withKey(String key){
        return new KeyedDataPoint(key, this.timeStampMs, this.value);
    }
}

...以这种方式,从原始的DataPoint<Long>开始,我将一些映射函数应用于value字段,并且该值变成Double。通过使用方法withNewValue,实例化new DataPoint<Double>

没问题。
public DataPoint<Double> map(DataPoint<Long> dataPoint) {
    double phase = (double) currentStep / numSteps;
    return dataPoint.withNewValue(phase);
}

我需要将此迁移到Scala,但我不知道该怎么做。我正在尝试做类似的事情:

class DataPoint[T1] (val timeStampMs: Long, val value: T1) {
    def withNewValue(value: T2): DataPoint[T2] = new DataPoint[T2](this.timeStampMs, value)
    def withKey(key: String): KeyedDataPoint[T1] = new KeyedDataPoint(key, this.timeStampMs, this.value)
}

...无法编译。在有关Scala协方差和相反方差的官方文档之后,还尝试了几种组合,但我仍处于使用Scala的第一步。

1 个答案:

答案 0 :(得分:3)

您仅缺少[T2]上的类型参数withNewValue

class DataPoint[T1] (val timeStampMs: Long, val value: T1) {
    def withNewValue[T2](value: T2): DataPoint[T2] = new DataPoint[T2](this.timeStampMs, value)
    def withKey(key: String): KeyedDataPoint[T1] = new KeyedDataPoint(key, this.timeStampMs, this.value)
}

Compiles just fine.