Abstract: 继续阅读 Scala with Cats,我们使用 Eq 来进一步巩固我们前面学到的 Type Class 的设计模式。Eq 的用途很简单,就是定义两种类型相等的条件。
Cat Eq 使用
目标:实现两个同类型的对象的比较。
1 | val obj1 = MyObj() |
在 Java 我们熟悉使用 .equal 方法来实现对象的比较,这里引入 Type Class 使用更加简洁。
案例1
实现代码:
1 | import cats.instances.int._ // for Eq |
和 Show 一样,我们只需要实现个对应类型的 Instance 即可,其中需要依赖一些基础类型的 Instance。
案例2
该案例实现两个 Date 类型的对象的比较:
1 | import java.util.Date |
Cat Eq 源码分析
Type Class 定义
1 | trait Eq[@sp A] extends Any with Serializable { self => |
接口的实现
我们在上一篇笔记中学习这一步需要进行接口的实现,由于 Cat 希望提供抽象的支持,所以它只提供基础的数据类型的实现,并且提供一系列的工厂方法帮助用户在客户端创建自定义类型的 instance。
基础类型 instance
Cat 并没有把每个 Type Class 的基础类型的实现分开,而是统一为基础类型的 Instance。我们使用 String 这个基础类型举例,其 Instance 的实现为:
1 | object string extends StringInstances |
我们可以看到其中 eqv 方法实现:
1 | override def eqv(x: String, y: String): Boolean = |
工厂方法
在 object Eq 中定义了一系列的方法帮助创建 Eq的Instance,比如 instance:
1 | /** |
该方法接受一个 lambda (函数)作为参数,这个函数就是用来比较数据类型判断相等的标准。其使用方法如下: A 是我们的目标对象,我们要给这个对象增加=== 的能力,这个能力的实现就是传入的函数,比如 Date类型,我们用其 getTime 方法返回值是否相等来判断两个 Date 是否相等。
1 | implicit val dateEq: Eq[Date] = |
注:函数调用小括号和花括号都是可以的,所以这里我们用小括号,上一节我们用的花括号。
语法 === 实现
最后就是语法糖,一般情况我们都是使用 Syntax,使用更加直观。
1 | trait EqSyntax { |
总结
我们通过 Eq 进一步巩固了 Type Class 模式,同时也学习了 Cat 的内部实现源码,对于其他 Cat 的 Type Class 原理基本和 Show 和 Eq 大同小异。