如何重写类型的隐词



我有以下问题,这可能是最好的例子:

1) 此代码在库中提供

sealed trait Base
class A extends Base
class B extends Base
class C extends Base
trait IntValue[T <: Base] {
  def value: Int
}
trait SomeApi {
  def apply[T <: Base : ClassTag]: Int
}
class ApiUsage(val api: SomeApi) {
  def someMethod() = {
    println(api[A])
    println(api[B])
    println(api[C])
  }
}

SomeApi#apply方法应根据Base特性的运行时类型返回Int值。我知道这个例子没有道理,但我尽量让它变得简单。在实际库中,此方法从actor系统返回对基于该类型的akka actor的引用。

2) 现在,我想使用ApiUsage类,并通过隐式Base特征的类型提供值,类似于

object Test extends App {
  implicit val aValue = new IntValue[A] {
    def value: Int = 10
  }
  implicit val bValue = new IntValue[B] {
    def value: Int = 20
  }
  implicit def defaultValue[T <: Base : ClassTag] = new IntValue[T] {
    def value: Int = 30
  }
  private val api = new SomeApi {
    def apply[T <: Base : ClassTag]: Int = findValue[T]
  }
  private def findValue[T <: Base : IntValue : ClassTag] =    
    implicitly[IntValue[T]].value
  val apiUsage = new ApiUsage(api)
  apiUsage.someMethod()
}

我想在那里创建ApiUsage类,并将其引用传递给我的SomeApi本地实现,该实现返回:-10适用于A类型-20用于B类型-30用于其他类型(C在这种情况下)

此测试在所有情况下都打印30

有没有什么方法可以用隐词优雅地解决这个问题?非常感谢

在不更改签名的情况下,最好的方法可能是

val api = new SomeApi {
  def apply[T <: Base : ClassTag]: Int = {
    val clazz = classTag[T].runtimeClass
    if (clazz == classOf[A]) 
      10
    else if (clazz == classOf[B]) 
      20
    else 
      30
  }
}

最新更新