在scala中指定特征约束

时间:2013-07-11 20:30:08

标签: scala traits

我想测试一些可堆叠的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

} 

其中每个测试子类将使用这样的可堆叠L覆盖trait。 这当然不起作用,因为L没有约束来指定它是一个特征。引用编译器,

  

类型L需要成为混合的特征

我也想过像

这样的东西
abstract LayerTest[L <: Layer] {
  //...
}

class TimeStampLayerTest extends LayerTest[TimeStampLayer] {}

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

有没有办法指定某个类型是特质?

1 个答案:

答案 0 :(得分:1)

您的代码问题比仅仅在L上缺少类型constrait以指定它是一个特征更为基础。 即使你能做到这一点,编译器应该怎么做?使用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 ...