racket - 是否可以在宏之外使用 extract-struct-info ?
问题描述
考虑以下球拍代码来获取accessor
给定结构的 s 列表:
#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
接受 a struct-info
)。
解决方案
您不能在运行时使用syntax-local-value
and 。extract-struct-info
您必须改用运行时结构自省。
如果你让你的结构透明,像这样:
(struct point [x y] #:transparent)
struct-info
然后您可以使用and从点实例中获得类似的值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
.
推荐阅读
- c# - 设备日期时间 - Xamarin 应用程序
- python - 具有有序编码的 LabelEncoder
- python - 在任何地方使用资源运行 Python 脚本
- angular - 当使用延迟加载 mat-tab 内容时
,在 mat-tab 内容中路由组件被初始化(构造函数和 Init)两次 - python - Python:查找列表中的异常值
- java - MinecraftForge 1.12 readImagetoBuffer 错误
- java - Spring异步请求处理
- javascript - 当所有对象的键相同且值可能不同时,如何将对象数组转换为单个对象
- mysql - mysql int 列与字符串匹配
- python - AttributeError:部分初始化的模块“cv2”没有属性“imread”