1

我想做这样的事情:

(define-field-magic color car)
(set! color "green")
(pretty-display color)

而不是这个:

(set-field! color car "green")
(pretty-display (get-field color car))
4

4 回答 4

4

改编自The Racket Guide的一种解决方案是:

(define-syntax color
  (syntax-id-rules (set!)
    [(set! color e) (set-field! color car e)]
    [(clock a ...) ((get-field color car) a ...)]
    [clock (get-field color car)]))

但可能有更好、更易读的方法。

于 2013-08-23T00:58:39.067 回答
1

这是对标题中问题的回答。

以下解决方案适用于公共领域。请注意,来自球拍/平局的 color% 字段是私有的。出于这个原因,我在下面定义了我自己的 color% 类:

#lang racket

(define color%
  (class object%
    (init-field [r 0]
                [g 0]
                [b 0]
                [a 1.0])
    (super-new)))

(define-syntax-rule (define-local id class-expr field-id object-expr)
  (begin
    (define get (class-field-accessor class-expr field-id))
    (define put! (class-field-mutator class-expr field-id))  
    (define-syntax id
      (syntax-id-rules (set!)
        [(set! id e) (put! object-expr e)]
        [id          (get object-expr)]))))

(define a-color (make-object color% 255 255 255 1.0))
(define-local red   color% r a-color)
(define-local blue  color% g a-color)
(define-local green color% b a-color)

red
(set! red 125)
red

输出是:

255
125
于 2013-08-25T12:26:54.173 回答
0

One way to do something similar to what you want, without having to use macros, is via SRFI 17:

(require srfi/17)
(define (bind-field field obj)
  (getter-with-setter
   (lambda ()
     (dynamic-get-field field obj))
   (lambda (val)
     (dynamic-set-field! field obj val))))

Now, you can do this (I renamed your object from car to obj, since car is a built-in function and you don't want to shadow that):

(define color (bind-field 'color obj))
(set! (color) "green")
(pretty-display (color))
于 2013-08-23T02:23:55.410 回答
0

基于安德烈斯的回答 - 我赞成 - 但可能更惯用:

(define-syntax color
  (syntax-id-rules (set!)
   [(set! id e) (set-field! color car e)]
   [(id a ...) ((get-field color car) a ...)]
   [id (get-field color car)]))
于 2020-04-22T13:48:33.343 回答