传值和队列

Pass-by-value and queue

据我了解,Scheme在调用函数时使用传值方式。我看到的队列的一种实现定义如下 (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 可以解决问题,但这里不是这种情况。

据我了解,queue 变量是一对(car 部分指向队列的头部,cdr 部分指向队列的末尾)。所以我看不出怎么定车!该变量的副本可能会更改原始对象本身的汽车部分(队列变量)。

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

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

在 Scheme 中,术语通常指的是 bindings。绑定或多或少是一个引用特定值的名称。例如,考虑以下代码:

(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! 只是调整给定绑定所指的内容,而不是值本身,因此其他绑定不受影响。