假设您有一个结构,如下所示:
(struct soldier (name rank serial-number) #:transparent)
(define s (soldier 'Smith 'private 100134))
如何找出soldier
或s
包含哪些字段?或它支持哪些通用接口,或具有什么结构类型属性?
(如果您已经知道答案,请跳过本节。)
最近几天,我一直在阅读有关struct的文档,但我一直无法弄清楚如何将这些片段组合在一起。我可能只是想念一些基本的信息,而这不向认识Racket的人说。
Reflection and Security的一章中有一个“ Structure Inspectors”部分,内容为:
检查器提供了对结构域和结构类型信息的访问,而没有普通的域访问器和变异器。
但是我还不知道如何让检查员来提供。
struct-info
和struct-type-info
提供了一些信息,但没有提供字段名称,接口,属性等:
> (struct-type-info struct:soldier)
'soldier
3
0
#<procedure:soldier-ref>
#<procedure:soldier-set!>
'(0 1 2)
#f
#f
struct->vector
和struct->list
提供对实例的内容和上述数据的访问,但仅此而已:
> (struct->vector s)
'#(struct:soldier Smith private 100134)
如果您可以向我展示如何检查结构类型以查看其中的内容的示例,则可能可以弄清楚我在这里看不到的任何即将变得显而易见的东西。
答案 0 :(得分:3)
字段名称在运行时不可用。但是,您可以在扩展时在结构名称上使用syntax-local-value
来获取一些信息。
一个简单的例子:
#lang racket
(require (for-syntax racket/struct-info))
(struct foo (a b))
(begin-for-syntax
(display (extract-struct-info (syntax-local-value #'foo))))
更新
在此示例中:
#lang racket
(require (for-syntax racket/struct-info))
(struct foo (a [b #:mutable] c))
(begin-for-syntax
(display (extract-struct-info (syntax-local-value #'foo))))
突变体的标识符列表为:(#f #<syntax:4:8 set-foo-b!> #f)
。
那只是第二个字段是可变的。
信息在扩展时可用,因此您可以通过调用扩展为(define info '(#f set-foo-b! #f)
或类似定义的宏来将信息传输到运行时。