常见类型类
Show、Ordering、Numeric
常见类型类 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
标准类型类
Scala 标准库提供了多个您每天都会使用、有时甚至没有意识到的类型类:
Ordering[A]— 定义如何比较值。Numeric[A]— 定义对数字执行的算术运算。Show风格的渲染(自定义实现,或 Cats 的Show)。
Ordering 赋能 sorted
List.sorted 需要一个隐式的 Ordering[A]。标准库为数字、字符串等类型提供了实例。
@main def run(): Unit = {
println(List(3, 1, 2).sorted)
println(List("pear", "apple", "fig").sorted)
}自定义 Ordering
传入一个显式的 Ordering,即可采用不同的排序方式,例如按降序排序或根据派生键排序。
@main def run(): Unit = {
val nums = List(3, 1, 2)
println(nums.sorted(Ordering.Int.reverse))
val words = List("bbb", "a", "cc")
println(words.sortBy(_.length))
}样例类的 Ordering
为您自己的类型提供一个 Ordering 实例,这样就可以对该类型的集合进行排序。Ordering.by 可以根据某个键派生出排序规则。
case class Person(name: String, age: Int)
object Main {
implicit val byAge: Ordering[Person] = Ordering.by(_.age)
def main(args: Array[String]): Unit = {
val people = List(Person("A", 30), Person("B", 20))
println(people.sorted)
}
}Numeric 抽象出算术运算
Numeric[A] 让您可以编写适用于任意数字类型的函数。对列表使用 sum 时就依赖于它。
@main def run(): Unit = {
println(List(1, 2, 3).sum)
println(List(1.5, 2.5).sum)
}编写泛型数值代码
借助上下文界定 [A: Numeric],您可以用泛型方式对任意数字类型执行加法或乘法。请通过 Numeric[A] 使用实例提供的运算。
object Main {
def addAll[A: Numeric](xs: List[A]): A = {
val num = implicitly[Numeric[A]]
xs.foldLeft(num.zero)(num.plus)
}
def main(args: Array[String]): Unit = {
println(addAll(List(1, 2, 3)))
println(addAll(List(1.0, 2.0, 3.5)))
}
}数值运算符
导入实例的 Implicits 后,泛型数字类型就可以使用常见运算符(+、*),让代码读起来更加自然。
object Main {
def square[A](a: A)(implicit num: Numeric[A]): A = {
import num._
a * a
}
def main(args: Array[String]): Unit = {
println(square(5))
println(square(2.5))
}
}Show 类型类
Show 会以类型安全的方式将值渲染为文本(不同于对所有对象都存在的 toString)。Cats 提供了它;这里展示一个最小实现。
trait Show[A] { def show(a: A): String }
object Show {
implicit val intShow: Show[Int] = n => s"Int($n)"
def apply[A](implicit s: Show[A]): Show[A] = s
}
object Main {
def main(args: Array[String]): Unit = {
println(Show[Int].show(42))
}
}Ordering 与 max/min
集合中的 max、min 和 maxBy 等方法,底层都使用了 Ordering。
@main def run(): Unit = {
val xs = List(4, 9, 1, 7)
println(xs.max)
println(xs.min)
println(List("a", "abc", "ab").maxBy(_.length))
}组合 Ordering
您可以对元组使用 Ordering.by 构建组合排序规则,先按一个字段排序,再按另一个字段排序。
case class Rec(group: String, score: Int)
object Main {
implicit val ord: Ordering[Rec] = Ordering.by(r => (r.group, -r.score))
def main(args: Array[String]): Unit = {
val data = List(Rec("b", 5), Rec("a", 1), Rec("a", 9))
data.sorted.foreach(println)
}
}为什么这里使用类型类
由于比较和算术运算都是类型类,因此只需提供实例,同一个 sorted 或 sum 就可以用于内置类型和您自己的类型。这就是标准库对特设多态的使用。
快速检查
测试您对标准类型类的掌握程度。
回顾
您已经了解了常见的标准类型类:
Ordering[A]驱动sorted、max和min;可以使用Ordering.by构建。Numeric[A]支持泛型算术运算,并为sum提供支持。Show风格的类型类可以以类型安全的方式渲染值。
常见问题解答
「常见类型类」课时是免费的吗?
是的 — 「常见类型类」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
「常见类型类」这节课中我会学到什么?
Show、Ordering、Numeric 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「常见类型类」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?
能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。