通过这个答案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的第一步。
答案 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)
}