考虑以下球拍代码,以获取给定结构的accessor
个列表:
#lang racket
(require (for-syntax syntax/parse racket/struct-info racket/list))
(struct point [x y])
;; get the list of accessors from a struct
;; ex. (get point) = '(point-x point-y)
(define-syntax (get stx)
(syntax-parse stx
[(_ struct)
(define struct-info (extract-struct-info (syntax-local-value #'struct)))
(define accessors-list (map syntax-e (fourth struct-info)))
#``(#,@accessors-list)]))
(get point)
使用syntax-local-value
,我们可以提取受模式变量struct
约束的标识符的值。
使用extract-struct-info
,我们可以列表形式(具有6个元素)提取结构类型信息。从这里可以提取访问者列表(这是列表中的第四个元素)。
问题
如何在非宏级别访问有关结构的信息(如Structure Type Transformer Binding中所示)?上面的两个函数不能在转换器外部的结构上直接使用,因为该结构是此时的过程(extract-struct-info
接受struct-info
)。
答案 0 :(得分:4)
您无法在运行时使用syntax-local-value
和extract-struct-info
。您必须改为使用运行时结构自省。
如果使结构透明,则像这样:
(struct point [x y] #:transparent)
然后您可以使用struct-info
和struct-type-info
从点实例中获取类似的值:
(define a-point (point 3 4))
(define-values (type skipped?) (struct-info a-point))
;; type = #<struct-type:point>, skipped = #f
(define-values (name inits autos acc mut imms super super-skipped?)
(struct-type-info type))
(acc a-point 0) ;; => 3
上面type
的值与struct:point
相同(由结构定义隐式定义),因此,如果您知道要专门处理点结构,则可以改用该值。不过,您仍然需要#:transparent
(或者您需要足够强大的检查器)才能使用struct-type-info
。