是否可以在宏外使用extract-struct-info?

问题描述 投票:3回答:1

考虑以下球拍代码来获取给定结构的accessors列表:

#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)。

racket
1个回答
4
投票

你不能在运行时使用syntax-local-valueextract-struct-info。您必须使用运行时struct introspection。

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

(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

© www.soinside.com 2019 - 2024. All rights reserved.