首页 > 解决方案 > 通过隐式类重载泛型方法

问题描述

当我尝试通过隐式类为类创建扩展并重载现有的泛型方法时,它失败并出现编译错误:

error: overloaded method value getAs with alternatives:
  (fieldName: String)String <and>
  (i: Int)String
 cannot be applied to (FooField.type)
       r.getAs[String](FooField)

虽然通过隐式重载普通(非泛型)方法可以正常工作。在 Scala 2.12.10 上试过。链接到scastie。我错过了什么?编码:

trait Row {
    // Two overloads for `getAs[T]`
    def getAs[T](i: Int): T
    def getAs[T](fieldName: String): T

    // Two overloads for `get`
    def get(i: Int): String
    def get(fieldName: String): String
}

trait Field {
    def columnName: String
    def columnDescription: String
}
case object FooField extends Field {
    def columnName: String = "Foo"
  def columnDescription: String = "Foo desc"
}

object Implicits {
  implicit class RowEx(val r: Row) extends AnyVal {
    def getAs[T](field: Field): T = r.getAs[T](field.columnName)
    def get(field: Field): String = {
      println(s"RowEx.get: field")
      r.get(field.columnName)
    }
  }
}

object Main {
  import Implicits._
  // Create some instance of `Row`
  val r = new Row {
    def getAs[T](i: Int): T = i.toString.asInstanceOf[T]
    def getAs[T](fieldName: String): T = fieldName.toString.asInstanceOf[T]
    def get(i: Int): String = i.toString
    def get(fieldName: String): String = fieldName
  }

  def main(args: Array[String]): Unit = {
    // Call extension method => `RowEx.get`
    println(r.get(FooField))

    // Call extension method => `RowEx.get`
    // Won't compile with compilation error:
    /*
    overloaded method value getAs with alternatives:
      (fieldName: String)String 
      (i: Int)String
     cannot be applied to (FooField.type)
    */
    println(r.getAs[String](FooField))
  }
}

打开了一个bug:https ://github.com/scala/bug/issues/11810

标签: scalagenericsimplicit

解决方案


推荐阅读