-
Notifications
You must be signed in to change notification settings - Fork 21
/
05.5 结构的比较
51 lines (38 loc) · 1.81 KB
/
05.5 结构的比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
5.5 结构的比较
一个通用的equal?比较自动出现在透明的结构类型的字段上,但是equal?默认仅针对不透明结构类型的实例标识:
(struct glass (width height) #:transparent)
> (equal? (glass 1 2) (glass 1 2))
#t
(struct lead (width height))
> (define slab (lead 1 2))
> (equal? slab slab)
#t
> (equal? slab (lead 1 2))
#f
通过equal?支持实例比较而不需要使结构型透明,你可以使用#:methods关键字、gen:equal+hash并执行三个方法来实现:
(struct lead (width height)
#:methods
gen:equal+hash
[(define (equal-proc a b equal?-recur)
; 比较a和b
(and (equal?-recur (lead-width a) (lead-width b))
(equal?-recur (lead-height a) (lead-height b))))
(define (hash-proc a hash-recur)
;计算a的第一个hash代码
(+ (hash-recur (lead-width a))
(* 3 (hash-recur (lead-height a)))))
(define (hash2-proc a hash2-recur)
;计算a的第二个hash代码
(+ (hash2-recur (lead-width a))
(hash2-recur (lead-height a))))])
> (equal? (lead 1 2) (lead 1 2))
#t
列表中的第一个函数实现对两个lead的equal?测试;函数的第三个参数是用来代替equal?实现递归的相等测试,以便这个数据循环可以被正确处理。其它两个函数计算用于哈希表的一级和二级哈希代码:
> (define h (make-hash))
> (hash-set! h (lead 1 2) 3)
> (hash-ref h (lead 1 2))
3
> (hash-ref h (lead 2 1))
hash-ref: no value found for key
key: #<lead>
这第一个函数提供gen:equal+hash,不需要递归比较结构的字段。例如,表示一个集合的结构类型可以通过检查集合的成员是相同的来执行相等操作,独立于内部表示的的元素顺序来实现相等。只要注意哈希函数对任何两个假定相等的结构类型都会产生相同的值。