有人能简单地向我解释一下如何在方案中实施消息传递?我认为我对消息传递的整个概念一点都没有。
答案 0 :(得分:2)
答案 1 :(得分:0)
以下示例定义了一个实现简单计算器的闭包。函数 make-calculator
类似于面向对象语言调用的构造函数。区别在于:make-calculator
返回一个函数,而构造函数返回对象值。在面向对象语言中,对象值是第一类值。 Scheme 没有这样的值。对象第一类值提供访问对象成员变量和对象方法的功能。在 Scheme 中,必须通过调度函数的定义来模拟此功能。 make-calculator
返回这样的函数。 make-calculator
的主体定义了
a
和b
(成员变量)set-a!
和 set-b!
(访问器)addition
、subtraction
、multiplication
和 division
(方法)以上定义是闭包 make-calculator
的局部定义。在面向对象的语言中,它们被称为私有的。 dispatch 函数使函数公开并保持变量私有。这是有效的,因为调度函数可以访问 make-calculator
闭包的本地范围。 dispatch 函数接受一条消息并返回匹配的函数。这将本地函数暴露给调度函数的调用者。
(define (make-calculator)
(define a)
(define b)
(define (set-a! value)
(set! a value))
(define (set-b! value)
(set! b value))
(define (addition)
(+ a b))
(define (subtraction)
(- a b))
(define (multiplication)
(* a b))
(define (division)
(/ a b))
(lambda (message)
(case message
((set-a!) set-a!)
((set-b!) set-b!)
((addition) addition)
((subtraction) subtraction)
((multiplication) multiplication)
((division) division))))
首先必须调用构造函数来创建一个“对象”。 calc
是 dispatch 函数,它接受不同的消息,只是符号。
(define calc (make-calculator))
发送消息意味着调用带有符号参数的调度函数。下面将消息 set-a!
发送到 calc
,它返回本地函数 set-a!
的值。在这种情况下,消息的名称和本地函数的名称是相同的。这有助于避免混淆,但这不是必需的。
(calc 'set-a!) ;; => #<procedure set-a!>
因为 calc
返回一个函数,所以需要一个额外的应用程序来调用访问器。下面将 a
设置为 3,将 b
设置为 5。
((calc 'set-a!) 3)
((calc 'set-b!) 5)
现在我们可以计算:
((calc 'addition)) ;; => 8
((calc 'subtraction)) ;; => -2
((calc 'multiplication)) ;; => 15
((calc 'division)) ;; => 3/15
代码在 Chez Scheme 中是这样工作的。