【问题标题】:specifying trait constraint in scala在scala中指定特征约束
【发布时间】:2013-07-12 17:45:20
【问题描述】:

我想测试一些可堆叠的traits,它们是从这样的一个扩展而来的:

trait Layer{
  def write(s:String): String
}

每个人都以某种方式处理传入的字符串,然后将其传递给下一层,例如:

trait TimeStampLayer { 
  abstract override def write(s:String) = System.nanotime + super.write(s)
} 

我的想法是编写一个带有这样一个夹具的基础测试类:

abstract LayerTest { 

   type L

   val layer = new BaseLayer with L      // BaseLayer would be one that does nothing

} 

每个测试子类都会用这样一个可堆叠的trait 覆盖L。 这当然行不通,因为L 没有任何限制来指定它是一个特征。引用编译器,

类型 L 需要是一个特征才能混入

我也想到了类似的东西

abstract LayerTest[L <: Layer] {
  //...
}

class TimeStampLayerTest extends LayerTest[TimeStampLayer] {}

但我也不能将 L 限制为一种特质,或者至少不知道如何去做

有没有办法指定一个类型是一个特征?

【问题讨论】:

  • 有什么理由不能将图层表示为函数String =&gt; String 并使用函数组合?

标签: scala traits


【解决方案1】:

您的代码的问题比仅仅在L 上缺少类型约束来指定它是一个特征更为根本。 即使你能做到这一点,编译器应该怎么做?当使用new 运算符时,类型必须是完全已知的,但这里L 是一个抽象类型,所以new BaseLayer with L 在你调用new 时是完全未知的。因此,编译器无法知道在这里做什么。

您应该做的只是将layer抽象化,并让具体的子类执行实例化。

trait Layer{
  def write(s: String): String
}
trait TimeStampLayer extends Layer{ 
  abstract override def write(s: String) = System.nanoTime + super.write(s)
} 
trait BaseLayer extends Layer {
  def write(s: String) = s
}
abstract class LayerTest { 
   type L <: Layer
   val layer: L // Note that this is abstract
}
class MyTest extends LayerTest {
  class L extends BaseLayer with TimeStampLayer
  val layer = new L // We instantiate it here in the conrete test
}

请注意,减轻痛苦我使用的事实是您可以通过同名的具体类直接实现抽象类型 (class L extends ...)

【讨论】:

  • L 类型在运行时未知,但在编译时未知,因为它由 type 指示。我的想法是编译器可以为每个具有正确类型的子类覆盖createLayer 函数。嗯,听起来像是宏的工作......我会看看我能不能让它工作!感谢class L extends ... 的伎俩,不知道那个!
  • 问题与试图定义类似这样的东西相同:trait Factory[T] { def create: T = new T }。你可以说编译器应该为每个子类覆盖create,但泛型类或方法的一个基本属性是它们只编译一次。泛型在这方面与 C++ 模板有很大不同,后者在非常使用时被实例化(使得可以完全按照您的意愿执行此操作)。
  • create 实现为宏将无济于事,因为LayerTest 仍将只编译一次。可能的工作是让create 将实际实例化委托给一个类型类(由要实例化的类型参数化的工厂,隐式传递)并提供该工厂的单个隐式值,以宏的形式实现。
猜你喜欢
  • 1970-01-01
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 2010-11-23
相关资源
最近更新 更多