在Racket中,我想使用struct的字段名进行元编程。
例如:
(struct pt [x y])
(struct-fields pt) ;; -> '(x y)
答案 0 :(得分:1)
你做不到。你可以获得访问者,这里有pt-x
和pt-y
,但你不能单独使用x
和y
。为什么是这样?嗯,原因之一是实际上可能存在重复。考虑一个涉及一些有害结构子类型的场景:
#lang racket/base
(struct A [x] #:transparent)
(struct B A [x] #:transparent)
现在,B
类型的结构有两个x
字段,A-x
和B-x
。因此,当涉及子类型时,任何尝试单独使用字段名称与结构体的宏都会被破坏。
您可以做的是使用访问者,您可以使用syntax-local-value
加extract-struct-info
来实现,然后查看结果列表的第四个元素。但是,老实说,我认为这工作太多了,所以我写了一个语法课来为你做所有艰苦的工作。安装syntax-classes
包并使用struct-id
语法类:
#lang racket/base
(require (for-syntax racket/base
syntax/parse/class/struct-id)
syntax/parse/define)
(define-simple-macro (struct-accessors id:struct-id)
(list id.accessor-id ...))
> (struct pt [x y] #:transparent)
> (struct-accessors pt)
'(#<procedure:pt-x> #<procedure:pt-y>)