2016-09-30 83 views
1

我有一个单元测试,它测试了一些解决方案。但是这个测试代码也可以用于测试其他非常类似的解决方案。我想提出的是测试的代码是通用的被应用到这两种解决方案,如:使用类型参数写入函数

describe("when table contains all correct rows") { 
     it("should be empty") { 
     def check[T](func: T => List[Row]) = { 
      val tableGen = new TableGenerator() 
      val table: Vector[Row] = tableGen.randomTable(100) 
      .sortWith(_.time isBefore _.time).distinct 
      val result: List[Row] = func(table) 
      assert(result.isEmpty) 
     } 

     check(Solution.solution1) 
     check(Solution.solution2) 
     } 
    } 

其中的解决方案有两类:

solution1: IndexedSeq[Row] => List[Row] 
solution2: Seq[Row] => List[Row] 

如何检查()函数必须写成能够做到这一点? 什么是最好的方法来写这个(可能以其他方式)与消除代码重复?

更新: 当我尝试编译这段代码,我得到类型不匹配的错误func(table)

Error:(36, 29) type mismatch; 
found : table.type (with underlying type scala.collection.immutable.Vector[com.vmalov.tinkoff.Row]) 
required: T 
      val result = func(table) 
+0

为什么你认为你需要做什么吗?这个'check'函数应该已经可以做到这一点,并且没有重复的代码在你展示的内容中被消除。 –

+0

一旦我试图编译我得到类型不匹配的错误:发现矢量[行],需要T(表我传递给func)。 第二个问题是关于可能存在另一个更好/更可靠的方法来抽象这样的事情。 – likern

+0

你应该在问题中加上。 –

回答

4

对于这个工作,你需要能够通过一个Vector[Row]func,所以任何Vector[Row]必须是一个T;即TVector[Row]的超类型。您可以通过使用类型参数限制这个告诉编译器:

def check[T >: Vector[Row]](func: T => List[Row]) 

或者,由上述推理,功能T => List[Row]也将是一个功能Vector[Row] => List[Row]正是当TVector[Row]的超类型,以及Scala编译器知道这个(功能是反变换在他们的参数类型(s))。所以这个签名等同于简单的

def check(func: Vector[Row] => List[Row]) 

当然,你可以概括这一点,但多少要看您的具体愿望。例如。您可以替换List[Row]Seq[Row](无处不在),或与一类参数,并通过一个额外的功能check

def check[A](func: Vector[Row] => A)(test: A => Boolean) = { 
    val table = ... 
    val result = func(table) 
    assert(test(result)) 
} 

check(Solution.solution1)(_.isEmpty) // the compiler infers A is List[Row] 
+0

非常感谢!这正是我想要的。 – likern

3

你的话,也许就足以抽象的一个更具体的方式类型,比如界定你期待着一个Travesable。

def check[S[_] : Traversable](func: S[Row] => List[Row]) 

这将接受Seq或IndexedSeq作为有效参数,同时它也限制它。

我希望它能帮助

编辑:检查阿列克谢·罗曼诺夫回答,因为有了这个,你将无法FUNC你做的方式来调用。比较遗憾的是

高清检查(FUNC:矢量[行] =>列表[行])

+0

我想你是指'S [X] <:可穿越[X]'。 –

+0

这似乎没有解决这个问题,我太快地回答:P但Alexey Romanov似乎已经很好地回答了这个问题。 – FerranJr

+0

感谢您的回复。但的确,这并不能解决问题。 – likern