来自经验丰富的计划器 150的第150页中的以下函数通过改变每个列表的cdr来确定两个列表是否具有相同的标识(即占用相同的内存),然后检查更改是否同时影响了两者: 现在,如果我按如下方式定义 并评估 函数返回#f,调试器(Dr。Racket)确认这两个列表 - 自第二个参数以来应该共享其大多数成员是第一个参数的正确子集 - 实际上有不同同一成员的副本。这怎么可能?! 略微改变这个想法: 现在 [编辑答案在被接受的帖子评论链的底部] (define same?
(lambda (c1 c2)
(let ((t1 (cdr c1))
(t2 (cdr c2)))
(set-cdr! c1 1)
(set-cdr! c2 2)
(let ((v (= (cdr c1) (cdr c2))))
(set-cdr! c1 t1)
(set-cdr! c2 t2)
v))))
a_list
:(define a_list (list 'a 'b 'c 'd))
(same? a_list (cdr a_list))
(set-cdr! (cddr a_list) a_list)
a_list
是周期性的。如果我用same?
测试这个函数,它只在两个参数同步时注册#t,即(same? a_list a_list)
和(same? a_list (cdddr a_list))
。
答案 0 :(得分:4)
same?
函数不会检查两个列表是否共享元素。
它检查两对(即两个cons单元格)是否相同。
在(define a_list (list 'a 'b 'c 'd))
中你有4对。
在(same? a_list (cdr a_list))
中,您检查是否第一个
和第二对是同一对,因为它们不是,
same?
会返回#f
。
关于:
..和调试器(Dr. Racket)确认这两个列表 - 哪个 因为第二个论点是a,所以应该分享他们的大多数成员 第一个适当的子集 - 实际上有不同的副本 同样的成员。这怎么可能?!
您能更准确地了解如何在DrRacket中查看此内容吗?
两个列表a-list和(cdr a-list)共享成员。
编辑:
假设c1
和c2
是两个不同利弊单元的名称:
c1: (foo . bar) c2: (baz . qux)
现在我们评估(set-cdr! c1 1)
并获取:
c1: (foo . 1) c2: (baz . qux)
现在我们评估(set-cdr! c2 2)
并获取:
c1: (foo . 1) c2: (baz . 2)
然后我们将cdrs
与(= (cdr c1) (cdr c2))
进行比较。
由于cdrs
不同,我们得到#f
。
结论:当cons细胞不同时,相同?返回#f。
现在假设c1
和c2
是同一个缺点单元格的名称:
c1 = c2: (foo . bar)
现在我们评估(set-cdr! c1 1)
并获取:
c1 = c2: (foo . 1)
现在我们评估(set-cdr! c2 2)
并获取:
c1 = c2: (foo . 2)
然后我们将cdrs
与(= (cdr c1) (cdr c2))
进行比较。
由于cdrs
相同,我们得到#t
。
结论:当缺点单元格相同时,same?
会返回#f
。
编辑2
检查cons小区c
是否是其中之一
l
的cons细胞使用此:
(define (loop c l)
(cond
[(null? l) #f]
[(same? c l) #t]
[else (loop c (cdr l))]))