【问题标题】:How to call a generic method with an anonymous type involving generics?如何使用涉及泛型的匿名类型调用泛型方法?
【发布时间】:2011-02-18 07:27:03
【问题描述】:

我得到了这个有效的代码:

  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 =”的变量我想要
    它的 type 是匿名类, 不是 Foo[Int],因为它添加了方法
    (本例中为 someMethod)

有什么想法吗?

我认为第二个失败是因为 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
  }

【问题讨论】:

  • 嗯,很高兴听到 :) 希望它很快就会发布!
  • 您的错误表明存在协方差问题(尽管X 应该从未被推导出为Nothing)...试过class Foo[+T]
  • 这行得通,谢谢.. 但破坏了我的其他代码。 class Foo[+T] { var _val: Option[T] } 编译失败。 "协变类型 T 出现在类型 Option[T] 的值 _val 的逆变位置"
  • 认为这只是 2.7.7 中的一个错误?

标签: generics scala type-inference


【解决方案1】:

Dario 建议让 Foo 中的 T 协变:

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 增加了太多限制,例如我不能有 Option[T] 类型的 var 成员变量。

协变类型 T 出现在 setter val= 参数的类型 Option[T] 中的逆变位置

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 2012-01-11
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多