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
大同小异。