【问题标题】:Can I use scala type parameters with a val?我可以将 scala 类型参数与 val 一起使用吗?
【发布时间】:2020-06-13 07:21:13
【问题描述】:

我正在通过一些练习来习惯 Scala 的类型系统。我有一个用于运行单元测试的辅助函数,我在其中指定函数的输入和预期输出。在这种情况下,我正在测试的函数返回列表的前 n 个元素:

val inputs: List[TestCase[(List[Any], Int), List[Any]]] = List(
      TestCase(
        input = (List('a', 't', 'o'), 2),
        output = List('a', 't')
      ),
      TestCase(
        input = (List("Vegetable", "Fruit"), 4),
        output = List("Vegetable", "Fruit")
      ),
      TestCase(
        input = (List(3.14, 6.22, 9.5), -7),
        output = Nil
      )
    )

我的问题是是否可以为此 input val 指定类型参数。 List[Any] 没问题,但我想以某种方式指定输入列表与输出列表具有相同类型的元素。像这样的东西(顺便说一句不起作用):

val inputs[SameType]: List[TestCase[(List[SameType], Int), List[SameType]]] = ...

如果有任何建议,我将不胜感激。也许类型参数不适合与 vals 一起使用?

如果你想知道为什么我不只是断言结果:这是因为我有同一个函数的多个实现,我不想为每个实现重复测试用例。

【问题讨论】:

    标签: scala generics types


    【解决方案1】:

    考虑像这样对模型进行参数化

    case class TestCase[T](input: (List[T], Int), output: List[T])
    

    所以现在我们可以定义,比如说,

    val inputs: List[TestCase[String]] = ???
    

    在 Scala 2 中,值定义不能参数化,但方法定义可以,例如

    def input[T](x: List[TestCase[T]]) = ???
    

    但是 Scala 3 可能会change 这样我们就可以编写

    val input = [T] => (x: List[TestCase[T]]) => ???
    

    另一种方法是使用广义约束,例如,

    def assertEquals[A, B](input: List[A], output: List[B])(implicit ev: A =:= B) = ???
    
    assertEquals(List(1), List("")) // error: Error: Cannot prove that Int =:= String
    

    请考虑munit 以获取广义约束的示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多