如何为Scala类传递implicit Ordering?实例化报错问题求解
Fixing Your Scala Person Case Class and Ordering Issue
Let's break down what's going wrong here and fix it step by step:
First, the Core Problems
- Your implicit definition is the wrong type: You wrote an
implicit defthat returns anInt(a single comparison result), but we need animplicit Ordering[Person]instance—the type class that defines how to compare any twoPersonobjects. - Including
Ordering[Person]as an implicit constructor parameter forPersonis unnecessary (and unusual): Sorting rules apply to thePersontype as a whole, not to individual instances. There's no need to attach an ordering to every singlePersonyou create.
Solution 1 (Recommended: Follow Scala Type Class Conventions)
Simplify your case class and define the correct implicit Ordering in the companion object:
// Remove the implicit parameter from the case class constructor case class Person(name: String, age: Int) object Person { // Option 1: Use Ordering.by for a concise, readable implementation implicit val ageOrdering: Ordering[Person] = Ordering.by(_.age) // Option 2: Manually implement Ordering if you need complex logic // implicit val ageOrdering: Ordering[Person] = new Ordering[Person] { // override def compare(a: Person, b: Person): Int = a.age compare b.age // } def main(args: Array[String]): Unit = { val people = Array(Person("aa", 30), Person("bb", 32), Person("cc", 19)) scala.util.Sorting.quickSort(people) // Automatically uses the implicit ageOrdering people.foreach(println) // Output: Person(cc,19), Person(aa,30), Person(bb,32) } }
Solution 2 (If You Must Keep the Implicit Constructor Parameter)
If you have a specific reason to attach an Ordering to each Person instance (this is rare), you still need to fix the implicit definition and ensure it's in scope when creating instances:
case class Person(name: String, age: Int)(implicit val ordering: Ordering[Person]) object Person { // Define the correct implicit Ordering instance implicit val ageOrdering: Ordering[Person] = Ordering.by(_.age) def main(args: Array[String]): Unit = { // Implicit ageOrdering is automatically passed to each Person constructor val people = Array(Person("aa", 30), Person("bb", 32), Person("cc", 19)) scala.util.Sorting.quickSort(people) people.foreach(println) } }
Why Your Original Code Failed
Your implicit def ageOrdering(a: Person, b: Person): Int was a function that compared two people and returned an integer, but Scala's Sorting.quickSort expects an Ordering[T] type class instance—not a one-off comparison function. This mismatch meant:
- When creating
Personinstances, the compiler couldn't find the required implicitOrdering[Person]parameter. - Even if instantiation worked,
quickSortwouldn't recognize your function as a valid ordering rule.
内容的提问来源于stack exchange,提问作者Aisatora
相关产品推荐
相关产品推荐

