Scheme 在Racket中,如何获取和设置对象的字段,就好像它是一个局部变量一样?

Scheme 在Racket中,如何获取和设置对象的字段,就好像它是一个局部变量一样?,scheme,field,racket,local-variables,Scheme,Field,Racket,Local Variables,我想这样做: (define-field-magic color car) (set! color "green") (pretty-display color) 与此相反: (set-field! color car "green") (pretty-display (get-field color car)) 一种解决方案(改编自)是: 但是可能有更好、更易读的方法。一个根据的解决方案是: 但是可能有更好、更可读的方法。一种不必使用宏即可完成类似操作的方法是: 现在,你可以这样做了。我将

我想这样做:

(define-field-magic color car)
(set! color "green")
(pretty-display color)
与此相反:

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

一种解决方案(改编自)是:


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

一个根据的解决方案是:


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

一种不必使用宏即可完成类似操作的方法是:

现在,你可以这样做了。我将你的对象从car重命名为obj,因为car是一个内置函数,你不想给它加上阴影:

(define color (bind-field 'color obj))
(set! (color) "green")
(pretty-display (color))

无需使用宏即可完成与所需类似的操作的一种方法是:

现在,你可以这样做了。我将你的对象从car重命名为obj,因为car是一个内置函数,你不想给它加上阴影:

(define color (bind-field 'color obj))
(set! (color) "green")
(pretty-display (color))

这是对标题中问题的回答

下面的解决方案适用于公共字段。请注意,来自racket/draw的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

这是对标题中问题的回答

下面的解决方案适用于公共字段。请注意,来自racket/draw的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

根据安德烈斯的答案——我投了更高的票——但可能有点惯用:

(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)]))

根据安德烈斯的答案——我投了更高的票——但可能有点惯用:

(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)]))