list - Scheme中列表(或其他内容)的副本

标签 list copy scheme racket

我是 Scheme 的新手,如果我用 set-car!/set-cdr! (甚至在本地)父列表也被修改。这是一个例子,我的意思是:

(define my-list '(1 2 3 4 5)) ; Original list

(define (function list) ; Some example function
   (let ((copy list))
        (set-car! copy 'new)
   (display copy)
)

(function my-list); will display (new 2 3 4 5)

my-list; but the original is changed "forever" and will be also '(new 2 3 4 5)

我的问题是:
有没有办法复制原始列表并仅在其上工作,所以最后不要更改原始列表?

最佳答案

您的代码 (let ((copy list))允许通过名称副本访问列表。所以当你 set-car!复制,你其实是set-car! 'ing 原始列表。

类似 lisp 的语言中的突变现象起初有点令人困惑。

由于您发现的原因,通常应避免突变。列表的一部分和漂浮的东西。这是因为在内部,列表中的每个节点都有两个部分 - car它的值是否可能指向另一个列表,它是cdr是它后面的部分 - 通常这是一些类似于 car 中的值的东西.

这使用 SRFI1 的列表复制功能解决了您的问题
(let ((copy (list-copy list))))

这是复制列表的一种方法(制作新列表)。这段代码并不完整。当我们在内部查看它时,它会在每个递归调用中添加一个列表片段。每个新列表部分的片段来自哪里? cdr通过调用 (list-copy (cdr list)) 生成,而 car只是采取 - 不是复制! - 从另一个列表。

(define (list-copy list)
  (if (null? list) '() (cons (car list) (list-copy (cdr list)))))

实验时您的结果是您列表中的汽车copy借自my-list .

这是一个更合适的版本:
(define (full-copy list)
(if (null? list) 
  '() 
  (if (list? list) 
      (cons (full-copy (car list)) (full-copy (cdr list)))
      list)))

只有 car 的代码已经改变。现在,这辆车被改造到了。唯一借用的部分是数字(所以当数字更特别时,这个副本就不行了)。我不确定 srfi1 版本是如何工作的。

let 语句只将一个标识符绑定(bind)到一个对象 - 对象不会被复制,您只是有另一种访问它的方法。因此,任何更改(使用突变,如以“!”结尾的函数)都会影响两者。

关于list - Scheme中列表(或其他内容)的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20802629/

相关文章:

css - 列表样式图像不工作 : no markers present

r - 嵌套命名列表到数据框

java - 单击按钮 - 将文件从 APK 包复制到 Android 路径。但如何呢?

cocoa - 如何在 Cocoa 中将文件夹复制到系统文件夹

list - 正常函数中的反引号、反引号和反引号拼接

java - 如何从流中获取列表列表而不是数组列表?

c# - 使用 C# 从 newtonsoft JSON 中提取嵌套值

R - file.copy 函数

macros - 方案:用于代码复制的宏或高阶函数?

lisp - 如何在 Scheme 的 eval 中使用外部变量?