【问题标题】:Sorting an array in-place in Scala在 Scala 中对数组进行就地排序
【发布时间】:2016-03-04 05:15:38
【问题描述】:

我试过了:

implicit class ArrayExtensions[A](a: Array[A]) {
  /**
   * Sort a slice [from, until) of this array
   */
  def sort(from: Int, until: Int)(implicit cmp: Ordering[A]) = java.util.Arrays.sort(a, from, until, cmp)
}

但是,我想我正在打a bug in the compiler

[error]  found   : Array[A]
[error]  required: Array[? with Object]
[error] Note: A >: ? with Object, but class Array is invariant in type T.
[error] You may wish to investigate a wildcard type such as `_ >: ? with Object`. (SLS 3.2.10)
[error]     def sort(from: Int, until: Int)(implicit cmp: Ordering[A]) = java.util.Arrays.sort(a, from, until, cmp)

我该如何解决这个问题?

【问题讨论】:

  • 我认为JVM可以是一个标签。我认为 Java 不应该是一个标签。
  • 直接调用java.util.Arrays.sort有什么问题?
  • @kostya:我刚刚发布了调用java.util.Arrays时遇到的编译错误
  • 我的意思是,如果你有val a: Array[Int],你可以打电话给Arrays.sort(a, from, until),它就可以工作。为什么要介绍ArrayExtensions
  • 我设法通过复制 scala.util.Sorting.quickSort 代码,将其中的 Array 替换为 mutable.IndexedSeq 并使用 quicksort(a.view(from, until)) 进行排序来使其工作。请参阅 gist.github.com/kolmar/5b891c6058b16757525b 我不确定为什么 Scala 不提供任何内置的 quickSort 方法来对可变序列进行就地排序。

标签: scala scala-collections scala-2.11 scala-generics


【解决方案1】:

问题的答案就在您引用的错误中:“Java 泛型数组不能与 Scala 值类型一起使用”。正如错误所说,真正的问题是错误消息没有太大帮助。问题是您对 A 的类型没有限制,但并非所有 Scala 类型都可以用作 Java 泛型类型参数,只有引用类型可以。试试这个:

implicit class ArrayExtensions[A <: AnyRef](a: Array[A]) {
    /**
     * Sort a slice [from, until) of this array
     */
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]) = java.util.Arrays.sort(a, from, until, cmp)
}

AnyRef 对应于 Java Object,而Any 包括非 Java 对象的 Scala 类型(如 Int)。

【讨论】:

  • 完整链接到 Scala 问题 issues.scala-lang.org/plugins/servlet/mobile#issue/si-5783。这本身不是错误,只是没有足够清晰的错误信息。
  • @pathikrit 它不能用于 Array[Int] 每个定义。您正在调用泛型 Java 方法,它在 Java 意义上仍然是泛型的,即仅适用于 Object 子类,而在 Java 中显然不是 int 。在 Scala 方面,Java 约束被解释为 AnyRef 的子类,而 AnyRef ~= Object,同样 Scala Int 不是。搜索专门的注释以获得 Int 的特殊情况。见scala-notes.org/2011/04/specializing-for-primitive-types
【解决方案2】:

所以,到目前为止,我已经这样做了:

a.slice(from, until).sorted.copyToArray(a, from)

但是,这并不理想,因为它需要两次额外的遍历。

【讨论】:

    猜你喜欢
    • 2011-07-06
    • 1970-01-01
    • 2020-09-11
    • 2011-07-29
    • 1970-01-01
    • 2011-12-20
    • 2010-11-11
    • 2020-06-24
    相关资源
    最近更新 更多