2

我有一个折叠函数,我想在许多不同的结构上使用,每个结构都有任意命名的字段。因此,我需要告诉 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但我不知道它到底是如何工作的。

4

1 回答 1

3

什么行不通

尽管您可以在运行自省结构类型,但我看不出如何在编译时在宏中使用它。因为在编译时,除了一段语法之外,您没有任何可提供的东西object-name——而不是具有类型的实时结构对象:

(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

    这类似于 Racketsort有一个可选#:key extract-key参数,这是一个应用于每个项目以获取用于排序的值的函数。例如,如果您正在对test structs 列表进行排序,则可以传递test-element访问器函数。

    - 或者 -

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

    (define test (hasheq 'element 0))
    (hash-ref test 'element)  ; => 0
    
于 2013-05-04T23:53:14.117 回答