【问题标题】:scala convert Array[Product] to Array[MyType]scala 将 Array[Product] 转换为 Array[MyType]
【发布时间】:2018-06-21 09:29:22
【问题描述】:

我有自己的班级:

case class QueueObject[K, V](priority: K, e: V)(implicit prior: K => Ordered[K]) {
  require(e != null, "Can't put null element in queue. Please put another type of data!")
  type PQObject = QueueObject[K, V]

  def eq(other: PQObject): Int = if (priority >= other.priority) 1 else -1
}

我在其他班级

case class QueueClass[K, V](container: Array[QueueObject[K, V]]) {
...
type PQObject = QueueObject[K, V]
type PQContainer = Array[PQObject]
val array: PQContainer = container
...

所以我尝试像这样更新我的数组:

def deleteElement(array: PQContainer):PQContainer = array.updated(0, array.lastOption).init

但是这个函数的结果是Array[Product with Serializable],所以我需要Array[PQObject]。 如何将结果类型转换为我自己的? (我是 Scala 的新手,所以请不要发火)

【问题讨论】:

  • K => Ordered[K] 应该是Ordering[K],它应该附加到QueueClass,而不是QueueObject。如果队列中的每个对象都有自己的关于如何比较优先级的想法,那是没有任何意义的。
  • 它会是什么样子? 案例类QueueObject[K : Ordering[K], V](priority: K, e: V) 像这样?
  • 而不是K: Ordering(没有[K])。但它本质上只是你现在拥有的语法糖(每个QueueObject 都有自己的Ordering)。我宁愿声明QueueClass[K: Ordering, V],然后将排序作为隐式参数添加到实际需要它的QueueObject 的方法中。实际上,我可能会尝试使QueueObject 成为QueueClass 中的内部类。此外,我不会覆盖eq,因为eq 是检查引用相等性的方法,应该返回Boolean
  • @AndreyTyukin 对不起,但我又遇到了问题。如果我这样做: case class QueueObject[K: Ordering, V](priority: K, e: V) { 我不能在我的新文件中使用 >=等于 override def equals(obj: PQObject): Boolean = if (this.priority >= obj.priority) true else false
  • IIRC,val ord = implicitly[Ordering[K]]; import ord._ 之类的东西应该可以解决问题。但是你可以直接传递implicit ord: Ordering[K]。切换到K: Ordering 而不是implicit ord: Ordering[K] 不是我的意思。我的观点是,如果每个条目 (K, V) 都有自己的顺序,那没有任何意义。顺便说一句:你的equals 甚至不是对称的。

标签: arrays scala type-conversion


【解决方案1】:

问题是您试图用lastOption 替换第一个元素。

lastOption 的类型是Option[PQObject],scala 编译器将PQObjectOption[PQObject] 的公共超类型推断为Product with Serializable——这是一个非常通用(无用)的类型。

试试这个:

array.lastOption.foreach(array.update(0, _))
array.init

编辑

由于init在数组为空时会抛出异常,所以你不妨直接使用last而不是lastOption

【讨论】:

  • 哦,非常感谢!)
  • 这个检查在 Scala 中是否与 init 相关 def deleteElement(array: PQContainer): PQContainer = if (array.nonEmpty) array.updated(0, array.last).init其他数组 ?
  • @TimofeyGusev:是的,这样会更好!
【解决方案2】:

问题在于array.lastOption。此调用的结果返回 Option[PQOBject] 并且 Scala 编译器检测到您的数组不是由相同类型的元素构建的,因此,编译器返回带有 Serializable 的 Product。如果你使用 last 而不是 lastOption 它会编译:

object testN1 {
  case class QueueObject[K, V](priority: K, e: V)(implicit prior: K => Ordered[K]) {
    require(e != null, "Can't put null element in queue. Please put another type of data!")
    type PQObject = QueueObject[K, V]

    def eq(other: PQObject): Int = if (priority >= other.priority) 1 else -1
  }

  case class QueueClass[K, V](container: Array[QueueObject[K, V]]) {
    type PQObject = QueueObject[K, V]
    type PQContainer = Array[PQObject]
    val array: PQContainer = container

    def deleteElement(array: PQContainer):PQContainer = array.updated(0, array.last).init
  }


}

【讨论】:

  • 非常感谢!)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 2015-02-04
  • 2022-12-17
  • 2019-07-12
  • 2016-06-10
相关资源
最近更新 更多