返回介绍

5.2 访问字段

发布于 2025-02-20 00:17:08 字数 1413 浏览 0 评论 0 收藏 0

当然,这个定义不怎么通用,因为它只适用于一个字段 x 。我们需要将其一般化:字段名必须作为参数传给 -read-write 消息。问题是,如何用字段名(符号)访问对象的词法环境中的同名变量。一个简单的解决方案是使用某种结构来保存字段值。方法的定义就是这样处理的,保存的是方法名称和方法定义之间的关联。不过,与方法表不同,字段绑定是(至少是潜在)可变的。Racket 不支持对关联表进行赋值,所以我们使用字典(更确切地说,哈希表),用 dict-refdict-set! 访问。

(define make-point
  (let ([methods (list (cons 'x? (λ (self)
                                    (λ () (self '-read 'x))))
                       (cons 'x! (λ (self)
                                  (λ (nx)
                                    (self '-write 'x nx)
                                    self))))])
    (λ (init-x)
      (letrec ([self
                (let ([fields (make-hash (list (cons 'x init-x)))])
                  (λ (msg . args)
                    (case msg
                      [(-read)  (dict-ref  fields (first args))]
                      [(-write) (dict-set! fields (first args)
                                                  (second args))]
                      [else
                       (apply ((cdr (assoc msg methods)) self) args)])))])
      self))))

> (let ((p1 (make-point 1))
        (p2 (make-point 2)))
    (+ ((p1 'x! 10) 'x?)
       (p2 'x?)))
12

请注意 make-point 现在保存了方法定义的列表,还有,被创建的对象捕获了 fields (字段) 字典(该字典先初始化,然后返回给对象)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文