按值传递和队列

时间:2015-04-22 20:21:26

标签: scheme

据我所知,Scheme在调用函数时使用pass-by-value。我看到的队列的一个实现定义如下(yet another scheme tutorial):

(define (make-queue)
  (cons '() '()))

(define (enqueue! queue obj)
  (let ((lobj (cons obj '())))
    (if (null? (car queue))
    (begin
      (set-car! queue lobj)
      (set-cdr! queue lobj))
    (begin
      (set-cdr! (cdr queue) lobj)
      (set-cdr! queue lobj)))
    (car queue)))

然后创建队列,并将其传递给enqueue!

(define q (make-queue))
;Value: q

(enqueue! q 'a)
;Value 12: (a)

如果只传递值,那么传递给函数的队列变量如何修改?我读到使用set-box和unbox可以做到这一点,但事实并非如此。

根据我的理解,队列变量是一对(汽车部分指向队列的头部,cdr部分指向队列的末尾)。所以我不知道如何定车!该变量的副本可以改变原始对象本身的汽车部分(队列变量)。

有人可以向我解释它是如何运作的吗?队列变量是否包装为一对地址?

1 个答案:

答案 0 :(得分:4)

Scheme与大多数动态语言一样,传递值,但它有效地传递对象引用(像Java这样的语言会称之为)。在像C这样的低级语言中,它就像传递指向值的指针一样。指针本身按值传递,但您可以使用它来获取它指向的基础(共享)值。

在Scheme中,命名法通常根据绑定来指代这一点。绑定或多或少是引用特定值的名称。例如,请考虑以下代码:

(let* ((a '(1 . 2))
       (b a))
  (set-car! b 3)
  (set! b 'something-else)

  (display a)
  (newline)
  (display b))

这将打印以下内容:

(3 . 2)
something-else

在该示例中,ab两个不同的绑定,它们绑定到相同的值,一个cons对。使用set-car!修改基础值,该对本身。相反,set!只是调整给定绑定所指的内容,而不是值本身,因此另一个绑定不受影响。