Как вызвать универсальный метод с анонимным типом, включающим дженерики? - PullRequest
9 голосов
/ 11 мая 2010

У меня есть этот код, который работает:

  def testTypeSpecialization: String = {
    class Foo[T]

    def add[T](obj: Foo[T]): Foo[T] =  obj

    def addInt[X <% Foo[Int]](obj: X): X = { 
      add(obj)
      obj
    }

    val foo = addInt(new Foo[Int] {
      def someMethod: String = "Hello world"
    })

    foo.someMethod
  }

Но я бы хотел написать так:

 def testTypeSpecialization: String = {
    class Foo[T]

    def add[X, T <% Foo[X](obj: T): T =  obj

    val foo = add(new Foo[Int] {
      def someMethod: String = "Hello world"
    })

    foo.someMethod
  }

Этот второй не компилируется:

нет неявного аргумента, соответствующего типу параметра (Foo [Int] {...}) => Foo [Nothing] найдено.

В основном:

  • Я бы хотел создать нового анонима класс / экземпляр на лету (например, новый Foo [Int] {...}) и передать его в метод «добавить», который добавит его к список, а затем вернуть его
  • Ключевым моментом здесь является то, что переменная из "val foo =" я бы хотел
    его тип является анонимным классом, не Foo [Int], так как он добавляет методы
    (SomeMethod в этом примере)

Есть идеи?

Я думаю, что 2-й сбой, потому что тип Int стирается. Очевидно, я могу «намекнуть» компилятору так: (это работает, но похоже на взлом)

  def testTypeSpecialization = {
    class Foo[T]

    def add[X, T <% Foo[X]](dummy: X, obj: T): T =  obj

    val foo = add(2, new Foo[Int] {
      def someMethod: String = "Hello world"
    })

    foo.someMethod
  }

1 Ответ

1 голос
/ 11 мая 2010

Дарио предложил сделать T-ковариантным в Foo:

def testTypeSpecialization: String = {
    class Foo[+T] {
      var _val: Option[T]
    } 

    def add[X, T <% Foo[X](obj: T): T =  obj

    val foo = add(new Foo[Int] {
      def someMethod: String = "Hello world"
    })

    foo.someMethod
  }

Но это добавляет слишком много ограничений для Foo, например, например. У меня не может быть переменной-члена var типа Option [T].

ковариантный тип T встречается в контравариантном положении в опции типа [T] параметра установщика val =

...