可以在宏外部使用extract-struct-info吗?

时间:2019-04-12 04:32:29

标签: racket

考虑以下球拍代码,以获取给定结构的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)。

1 个答案:

答案 0 :(得分:4)

您无法在运行时使用syntax-local-valueextract-struct-info。您必须改为使用运行时结构自省。

如果使结构透明,则像这样:

(struct point [x y] #:transparent)

然后您可以使用struct-infostruct-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