文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
6.4 清理类协议
我们引入 类 之后,又对它的协议(protocol)做了不少改变:
- 通过引入
lookup
将invoke
协议分成两部分,lookup
专门用于在类的层次结构中查找方法定义。 - 为了能够检索类的字段,添加了
all-fields
。构建类的时候通过它获取超类的字段列表,追加到当前定义的类的字段列表。 - 去除了字段访问的
read
/write
协议,以便正确地确定方法中的字段名称的作用域。
现在是时候反思一下类协议,看看这里的协议是不是最小化的,还是可以去掉一些部分。判断的标准是什么?既然我们正在讨论类的协议,它最好确实是依赖于类来处理消息。例如,之前介绍的 read
/ write
协议就可以删除。回忆一下:
....
[(read) (dict-ref (obj-values (first vals)) (second vals))]
[(write) (dict-set! (obj-values (first vals)) (second vals)
(third vals))]
....
这里有任何东西依赖于类函数中的自由变量(或者说,依赖于类对象的状态)吗?没有,唯一需要的输入是当前对象、要访问的字段的名称,以及可能写入的值。因此,我们可以直接把这些代码放在 ?
和 !
的展开中,从而有效地“编译掉”一层不必要的解释。
那么 invoke
呢? 来看看,它唯一做的是给自己发送一条消息,这个可以直接在扩展 ->
时做,这样调用本质上就独立于类了:
(defmac (-> o m arg ...)
(let ([obj o])
((((obj-class obj) 'lookup 'm) obj) arg ...)))
类协议的其他部分呢? all-fields
、 create
和 lookup
都访问了类的内部状态: all-fields
访问了 fields
; create
访问了 fields
和 class
本身; lookup
访问了 methods
和 superclass
。所以,我们的类只需要了解这三种信息。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论