【问题标题】:Operator < doesn't seem to support "Any" type How to fix it?Operator < 似乎不支持“Any”类型如何解决?
【发布时间】:2019-09-11 06:44:34
【问题描述】:

以下是用 Scala 编写的快速排序函数,用于对混合类型(int、double、float 等)列表进行排序。错误弹出并在第 3 行中说“类型不匹配,预期:T => 布尔值,实际:T => 任何无法解析符号

在 Windows 10 上运行的 Intellij IDE 给出了此错误消息。


    def qsort[T](list: List[T]): List[T] = list match {
      case Nil => Nil
      case pivot :: tail =>
        val(smaller, rest) = tail.partition(_ < pivot)
        qsort(smaller) ::: pivot :: qsort(rest)
    }

【问题讨论】:

  • 你会如何比较任意类型? T 需要是 Comparable 类型才能进行比较。
  • 在 C++ 中,可比较的类型不需要指定,只要它们有运算符
  • C++ 在您调用泛型函数时检查&lt; 等,但Scala 在编译该函数时会进行此项检查。 Scala 需要确保它适用于所有可能的T,因此您需要以某种方式限制允许的类型。您可以限制类型本身,或添加implicit 参数。

标签: scala generics operator-overloading


【解决方案1】:

Dmytro 的答案适用于任何可以隐式转换为Ordered[T] 的类型。这有点奇怪,在惯用的 Scala 中,人们通常更喜欢使用隐式的 Ordering 来代替。这样,顺序就完全脱离了T的实现。

def qsort[T : Ordering](list: List[T]): List[T]

签名使用上下文绑定,[T: Ordering] 是更详细的语法糖

def qsort[T](list: List[T])(implicit ev: Ordering[T]): List[T]

如果您来自 Java,OrderingOrderedComparatorComparable。请注意Ordering[T] 在本质上与T =&gt; Ordered[T] 非常相似,但我认为当您是初学者时更容易理解。它还为您提供了一组很好的方法来创建和操作Orderings。

最后,请注意,将List 用于快速排序等排序方法会导致性能非常差,因为附加到ListO(n)。如果性能是一个问题,请使用Array 和快速排序的就地实现。

【讨论】:

  • 修复后,使用的语法 TS _ &lt; pivot 仅在 val ev = Ordering[T] import ev._ 之后有效
【解决方案2】:

添加隐式参数

def qsort[T](list: List[T])(implicit ev: T => Ordered[T]) = ...

【讨论】:

    猜你喜欢
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    相关资源
    最近更新 更多