基于syntax-rules实现迷你面向对象系统:如何引入this变量?
用
syntax-rules实现带this的迷你Scheme面向对象系统 嘿,这个练习超有意思!我之前也折腾过用宏实现迷你OO,核心就是把this绑定到当前实例的消息分发函数上。下面是完全匹配你需求的实现,直接就能用:
(define-syntax oo-class (syntax-rules (attr method) [(_ ClassName ((attr attr-name attr-default) ...) ((method (method-name param ...) body ...) ...)) (define (ClassName) ;; 每个实例的属性都在闭包里,保证私有性 (let ([attr-name attr-default] ...) ;; 这里的`this`就是实例本身的消息分发器 (define (this msg) (case msg ;; 把每个方法映射到对应的lambda [(method-name) (lambda (param ...) body ...)] ... ;; 可选:支持直接获取属性(如果不需要可以删掉这行) [(attr-name) attr-name] ... [else (error "Unknown message:" msg)])) ;; 返回分发器作为实例对象 this))]))
核心逻辑说明
- 当你定义
(oo-class Counter ...)时,宏会生成一个构造函数Counter,调用它就会创建一个闭包实例。 - 属性
value和skip被包裹在实例的闭包里,每个实例都有自己的独立副本,完全隔离。 this其实就是当前实例的消息分发函数——在方法里写(this 'next),就是拿到当前实例的next方法lambda,接着用((this 'next))执行它。
测试你的示例代码
直接用你给出的代码测试,完全符合预期效果:
(oo-class Counter ((attr value 0) (attr skip 1)) ((method (next) (set! value (+ value skip)) value) (method (nextnext) ((this 'next)) ((this 'next))) (method (set-value newval) (set! value newval)) (method (set-skip newskip) (set! skip newskip)))) (define c (Counter)) ((c 'set-value) 23) ; 设置value为23 ((c 'next)) ; 返回24(23+1) ((c 'nextnext)) ; 返回26(24+1+1) ((c 'value)) ; 可选:获取当前value,返回26 ((c 'set-skip) 5) ; 设置步长为5 ((c 'next)) ; 返回31(26+5)
小扩展提示
如果不想让外部直接访问属性,把[(attr-name) attr-name] ...删掉就行,这样属性就完全是方法内部的私有变量了。
内容的提问来源于stack exchange,提问作者johnnyb
相关产品推荐
相关产品推荐

