【问题标题】:Scala Implicit Classtag without changing function contractScala Implicit Classtag 不改变函数契约
【发布时间】:2014-05-03 07:26:34
【问题描述】:

我有一个 trait,它实现了一个在 supertrait 中定义的方法,没有参数。我的方法实现需要一个在特征上定义的类型参数,但我不能添加(implicit ct:ClassTag[Foo]),因为这会改变方法的参数列表,并且不再算作在超特征上实现方法。具体来说:

import scala.reflect.ClassTag

trait AbstractFoo
trait Performance
trait Performer {def perform:Performance}

class FooPerformer[Foo <: AbstractFoo](implicit ct:ClassTag[Foo]) extends Performance {
  // do things
}        

trait Fooer[Foo <: AbstractFoo] extends Performer {
  def perform = new FooPerformer[Foo]
}

我需要 FooPerformer 上的隐式 ClassTag 来处理实现中的擦除。就目前而言,我在Fooer 中的perform 上收到一个缺少ClassTag 的编译错误,但如果我将其更改为:

trait Fooer[Foo <: AbstractFoo] extends Performer {
  def perform(implicit ct:ClassTag[Foo]) = new FooPerformer[Foo]
}

它不再在Performer 上实现perform

【问题讨论】:

  • 我没有收到缺少的ClassTag 错误,因此您的示例中缺少某些内容。您可以尝试使用 ClassTag 作为构造函数参数使 Fooer 成为一个类,除非 Fooer 真的必须是一个特征。
  • @wingedsubmariner 我刚刚回顾了导致这个问题的原始代码,FooPerformer 需要它自己的隐式ClassTag 来处理更深层的擦除,我更新了问题以反映那个。

标签: scala reflection implicit


【解决方案1】:

@wingedsubmariner 的意思是:

scala> class Fooer[Foo <: AbstractFoo : ClassTag] extends Performer {
     |   def perform = new FooPerformer[Foo]
     | }
defined class Fooer

还有,

scala> trait Fooer[Foo <: AbstractFoo] extends Performer {
     |   implicit protected def tag: ClassTag[Foo]
     |   def perform = new FooPerformer[Foo]
     | }
defined trait Fooer

scala> class Foob extends Fooer[AbstractFoo] {
     | protected def tag = reflect.classTag[AbstractFoo]
     | }
defined class Foob

【讨论】:

  • 很高兴,谢谢!我选择了第二个选项,因为 Fooer 需要保持特征。
猜你喜欢
  • 2017-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多