【问题标题】:Multidimensional data type in ScalaScala 中的多维数据类型
【发布时间】:2017-01-09 16:36:59
【问题描述】:

我有一个通用类,它由多维数据(即 n 维 Ararys 或 Vectors)构成。
在这种情况下,除了维度(Vector[Vector[T]] 但不是Vector[Array[T]])之外,我希望该类仅由一种类型(例如Vector)实例化。

具有此类签名:

class Foo[T](x: Vector[T], y: Bar[T])

我怎么能保证 T 会是 Vector[T]Vector[Vector[T]](或等等),但不是 Array[T]Vector[Array[T]]

【问题讨论】:

  • Vector[Array[Int]] 和 Vector[Array[Int]] 有什么区别,Vector[Array[Int]] 是二维的,集合类型不同,是不允许的,Vector[Array[Int]] 是一维的,只有一个集合类型(Vector),元素类型只是碰巧是Array[Int]?如果有人想给你一个 Vector[Vector[Int]],但他们只希望你处理外部维度而将内部维度留给他们,会发生什么?到目前为止,你想要的东西违反了 Liskov 替换原则:我可以传入一个 Vector[Any],但我不能给你一个 Vector[Seq[_]],即使它是一个子类型。

标签: arrays scala generics multidimensional-array vector


【解决方案1】:

虽然泛型在编译时通过类型擦除被清除,但您可以依赖“证据”机制。

证据是一种特殊的类型类,其目标只是见证类型 A 和类型 B 之间的关系。

A<:<B is a witness that A is a subclass of B
A=:=B is a witness that A is a B
A>:>B is a witness that A is a superclass of B

所以你可以写这样的东西

case class MyContainer[A,B](b:Vector[B])(implicit ev: B <:< Vector[A])

在您的类中,您可以简单地将向量 b 的每个元素视为向量 A,方法是将证据应用于每个项目:即

b flatMap {
   x => ev(x) map {_.toString}
} 

【讨论】:

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