5 Programmer-Defined Datatypes

来源:互联网 发布:找淘宝网店合作人 编辑:程序博客网 时间:2024/06/04 01:16

原文:自定义类型

5 程序员定义类型

5.1 Simple Structure Types: struct

5.2 Copying and Update

> (define p1 (posn 1 2))> (define p2 (struct-copy posn p1 [x 3]))> (list (posn-x p2) (posn-y p2))'(3 2)> (list (posn-x p1) (posn-x p2))'(1 3)

5.3 Structure Subtypes

(struct posn (x y))(struct 3d-posn posn (z))
> (define p (3d-posn 1 2 3))> p#<3d-posn>> (posn? p)#t> (3d-posn-z p)3; a 3d-posn has an x field, but there is no 3d-posn-x selector:> (3d-posn-x p)3d-posn-x: undefined; cannot reference undefined identifier; use the supertype's posn-x selector to access the x field:> (posn-x p)1

5.4 Opaque versus Transparent Structure Types

(struct posn (x y)        #:transparent)> (posn 1 2)(posn 1 2)

5.5 Structure Comparisons

(struct glass (width height) #:transparent)> (equal? (glass 1 2) (glass 1 2)) ;; 为什么这两个相等?因为使用了关键字#:transparent#t(struct lead (width height)) ;; 这里没有使用#:transparent所以,同值,也不会判断为相等> (define slab (lead 1 2))> (equal? slab slab)#t> (equal? slab (lead 1 2))#f
(struct lead (width height)  #:methods          ;; 使用这个关键字  gen:equal+hash     ;; 值是 `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的primary hash code     (+ (hash-recur (lead-width a))        (* 3 (hash-recur (lead-height a)))))   (define (hash2-proc a hash2-recur)                       ; 计算a的primary hash code     (+ (hash2-recur (lead-width a))             (hash2-recur (lead-height a))))])> (equal? (lead 1 2) (lead 1 2))#t

5.6 Structure Type Generativity

(define (add-bigger-fish lst)  (struct fish (size) #:transparent); new every time  (cond     [(null? lst) (lst (fish 1))]    [else (cons (fish (* 2 (fish-size (car lst))))                lst)]))> (add-bigger-fish null)(list (fish 1))> (add-bigger-fish (add-bigger-fish null)) ;; 多次执行(struct ...) 获得同名的,但是不同的结构体 fish-size: contract violation;            ;;  given value instantiates a different structure type with the same name  exptected: fish?  given (fish 1)(struct fish (size) #:transparent)(define (add-bigger-fish lst)  (cond   [(null? lst) (list (fish 1))]   [else (cons (fish (* 2 (fish-size (car lst))))               lst)]))> (add-bigger-fish (add-bigger-fish null))(list (fish 2) (fish 1))

5.7 Prefab Structure Types

跳然 transparent可以打印一个结构的内容,但是不能根据这个内容,得到原来的结构,number, string, symbol, list都是可以的.

一个 prefab结构类型,是一种Racket printer和expression reader己知的内建类型.很多这样的类型存在,它们由名称,字段数量,父类型和其它细节进行索引. prefab的打印,与 vector 类似,但是是以#s开头,而不是以#开头, 并且第一个元素就是这个类型的名字.

下面的例子,显示 sprout预定义结构类型的实例, 这个实例有一个字段.第一个实例的字段值是 'bean,第二个实例的字段值是'alfalfa:

> '#s(sprout bean)'#s(sprout bean)> '#s(sprout alfalfa)'#s(sprout alfalfa)

与数字和字符串一样, prefab结构是”self-quoting”,所以,可以省略前面的':

> #s(sport bean)'#s(sport bean)

当你使用#:prefab关键字,而不是生成新的结构类型时,你装得己存在的prefab的绑定:

> (define lunch '#s(sprout bean))> (define sprout (kind) #:prefab)> (sprout? lunch)#t> (sprout-kind lunch)'bean> (sprout 'garlic)'#s(sprout garlic)

The field name kind above does not matter for finding the prefab structure type; only the name sprout and the number of fields matters. At the same time, the prefab structure type sprout with three fields is a different structure type than the one with a single field:

5.8 More Structure Type Options

原创粉丝点击