Скала дисперсии, когда несколько типов - PullRequest
4 голосов
/ 17 марта 2019

С помощью этого ответа 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,и значение превращается в двойной.Используя метод 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 Ответ

3 голосов
/ 18 марта 2019

Вам не хватает только параметра типа [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)
}

Компилируется просто отлично.

...