Как реализовать функцию scala generi c, которая принимает подтип параметризованных признаков и возвращает его - PullRequest
3 голосов
/ 04 февраля 2020

Мне не нужна информация о типе T во время выполнения, поэтому я думаю, что ClassTag здесь бесполезен.

Мне просто нужно вернуть в моей функции тот же тип, который я принял в качестве аргумента.

class MyClass[T] extends A with B[T] with C with D

trait A
trait B[T] {
  def usefulMethod: Unit = println("B")
}
trait C
trait D {
 def usefulMethodToo: Unit = println("D")
}

Я пытался реализовать свою функцию следующим образом, но компилятор выводит Nothing


def helper[T, A <: B[T] with D](x: A): A = {
  x.usefulMethod
  x.usefulMethodToo
  x
}

helper(new MyClass[Int])

Может ли компилятор каким-то образом это определить?

Ответы [ 2 ]

4 голосов
/ 04 февраля 2020

Проблема в том, что он не может вывести T, но в этом (может быть, слишком упрощенном?) Случае он вам на самом деле не нужен:

def helper[A <: B[_] with D](x: A): A = {
  x.usefulMethod
  x.usefulMethodToo
  x
}

Этот обходной путь тоже работает:

def helper[T, A <: B[T] with D](x: A with B[T]): A = {
  x.usefulMethod
  x.usefulMethodToo
  x
}
2 голосов
/ 04 февраля 2020

Я не уверен на 100%, но я предполагаю, что в вашем конкретном случае MyClass также имеет тип, возможно, именно поэтому компилятор не может его определить. Я бы попробовал следующее:

def helper[T, A[_] <: B[_] with D](x: A[T]): A[T] = {
    x.usefulMethod
    x.usefulMethodToo
    x
  }

К сожалению, это не сработает для случая, подобного class IntMyClass extends B[Int] with D - но у меня пока нет лучших идей. Надеюсь это поможет!

...