球拍,功能中的访问结构字段

时间:2013-05-04 19:09:08

标签: racket structure

我有一个折叠函数,我想在许多不同的结构上使用,每个结构都有任意命名的字段。因此,我需要告诉fold函数传递给它的是什么类型的结构,以及要访问的字段。我需要这样的东西:

(define-struct test (element))
(define test_struct (make-test 0))

(define (getfield elementname structure)
  ((typeof structure)-elementname structure))

(getfield element test_struct)

最后一行相当于:

(test-element test_struct)

当然,以上都不是正确的语法,但它应该显示我想要的。基于stackoverflow的其他一些问题,似乎答案与syntax有关,但我不知道究竟是如何工作的。

1 个答案:

答案 0 :(得分:3)

什么行不通

虽然您可以introspect the struct type at run time,但我不知道如何在编译时在宏中使用它。因为在编译时除了一段语法之外你没有任何东西可以给object-name - 而不是一个带有类型的实时struct对象:

(require (for-syntax racket/syntax))
(define-syntax (get-field stx)
  (syntax-case stx ()
    [(_ field-name s)
     (with-syntax ([id (format-id stx
                                  "~a-~a"
                                  (object-name #'s) ; um, yeah, this won't work
                                  #'field-name)])
       #'(id s))]))

会改变什么呢?

  1. 您可以让fold - ish函数接受另一个参数 - 这是字段访问器函数。在您的示例中,test-element函数可以访问element结构类型的test字段。

    这类似于Racket的sort具有可选的#:key extract-key参数,该参数是应用于每个项目以获取用于排序的值的函数。例如,如果您对test struct的列表进行排序,则可以传递test-element访问者函数。

    - 或 -

  2. 您可以使用字典而不是结构。相当于上面的内容,但使用hasheq

    (define test (hasheq 'element 0))
    (hash-ref test 'element)  ; => 0