意外的数据持久性 [英] Unexpected persistence of data

查看:85
本文介绍了意外的数据持久性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含七个整数的列表,最初都是0,我们称它为数据".在运行程序的过程中,我想定期将那些整数之一的值增加1.在程序结束时,我将打印数据.一切都很好,除了在该程序的每个连续运行中,将来自上次运行的所有数据值都添加到该运行中的所有数据值中.我只需要此运行中的数据值.无论数据是类的方法内的局部变量,类的方法所调用的单独函数内的局部变量还是类的插槽,都会发生此意外行为.无论是否将数据的单个值增加incf或(setf值(1+值)),都会发生这种情况.当我重新加载程序时,数据重置为全零,但是当我再次运行该程序时,数据再次将所有上次运行的数据添加到该运行的数据中.当我增加一个数据值时,我使用函数nth,其中index是另一个对象的插槽的值.是什么原因导致我的数据"列表的值出现这种不受欢迎的持久性?

I have a list of seven integers, initially all 0s, let's call it "data." Periodically during the course of running my program I want to increment the value of one of those integers by one. At the end of the program I print data. All is fine, except that on each successive run of the program all the values of data from the last run are added to all the values of data from this run. I want only the values of data from this run. This unexpected behavior occurs whether data is a local variable within a class's method, a local variable within a separate function called by a class's method, or a slot of a class. It happens whether I increment the individual values of data by incf or (setf value (1+ value)). When I reload the program, data resets to all zeroes but when I run the program again data again adds all of the last run's data to this run's data. When I increment one of the values of data I use the function nth with index being the value of another object's slot. What could cause this unwelcome persistence of values of my "data" list?

推荐答案

您是否正在执行以下操作:

Are you doing something like this:

CL-USER> (defun foo ()
           (let ((value '(1)))     ; '(1) is literal data
             (incf (car value))))
FOO
CL-USER> (foo)
2
CL-USER> (foo)
3
CL-USER> (foo)
4
CL-USER> (foo)
5

引用的数据是文字数据;它只有一个副本,修改它的后果是不确定的.上面的行为很常见,但是您不能依赖它.当您这样做时,某些编译器会给出警告.例如,在SBCL中:

Quoted data is literal data; there's only one copy of it, and the consequences of modifying it are undefined. The behavior above is common, but you can't depend on it. Some compilers will give a warning when you do this. E.g., in SBCL:

CL-USER> (defun foo ()
           (let ((value '(1)))
             (incf (car value))))
; in: DEFUN FOO
;     (INCF (CAR VALUE))
; --> LET* 
; ==>
;   (SB-KERNEL:%RPLACA #:TMP1 #:NEW0)
; 
; caught WARNING:
;   Destructive function SB-KERNEL:%RPLACA called on constant data.
;   See also:
;     The ANSI Standard, Special Operator QUOTE
;     The ANSI Standard, Section 3.2.2.3
; 
; compilation unit finished
;   caught 1 WARNING condition
FOO

quote :

如果破坏性地修改文字对象(包括加引号的对象),后果是不确定的.

The consequences are undefined if literal objects (including quoted objects) are destructively modified.

使用例如(list 1)而不是'(1)创建可修改列表.在您遇到之前,这是一个常见的陷阱.在StackOverflow上还有其他一些问题提到了此问题.

Create modifiable lists with, e.g., (list 1), not '(1). This is a common pitfall until you've encountered it. There are some other questions on StackOverflow that mention this issue. A very specific one is

但是也有一堆:

  • LISP: Why doesn't mapcan accept my list give as parameters? (an interesting case with a literal list inside a lambda function passed to mapcan)
  • Unexpected List Duplication using Sort with Common Lisp
  • LISP - Global variable keep their old value after reinitialization
  • this answer to Sudoku table generator failure, lisp
  • How does Lisp function remember state in this code?
  • Do property lists in Common Lisp refer to some global state?
  • Why does this function return a different value every time?
  • Strange behavior invoking destructive Common LISP function receiving as argument a list created with quote
  • Local variable keeps data from previous execution
  • What is happening with this Common Lisp code?
  • Unexpected persistence of data (this question)
  • setf in a function does not work
  • duplicating and modifying the head of a list of list, in Lisp

Scheme中发生了相同的事情,尽管对文档的引用显然不同.对于R 5 RS,文档如下:

The same thing happens in Scheme, though the citations to the documentation are obviously different. For R5RS, the documentation is the following:

4.1.2文字表达式

...如第3.4节所述,更改常数是错误的(即 文字表达式的值)使用类似突变的程序 订车!或设置字符串!!

4.1.2 Literal expressions

… As noted in section 3.4, it is an error to alter a constant (i.e. the value of a literal expression) using a mutation procedure like set-car! or string-set!.

3.4存储模型

...在许多系统中,需要常量(即 文字表达式)以驻留在只读内存中.为了表达这一点, 可以方便地想象每个表示位置的对象 与一个标志关联,该标志告诉该对象是可变的还是可变的 一成不变的.在这样的系统中,文字常量和返回的字符串 按symbol-> string是不可变的对象,而所有由创建的对象 本报告中列出的其他程序是可变的.这是一个错误 尝试将新值存储到以表示的位置 不变的对象.

3.4 Storage model

… In many systems it is desirable for constants (i.e. the values of literal expressions) to reside in read-only-memory. To express this, it is convenient to imagine that every object that denotes locations is associated with a flag telling whether that object is mutable or immutable. In such systems literal constants and the strings returned by symbol->string are immutable objects, while all objects created by the other procedures listed in this report are mutable. It is an error to attempt to store a new value into a location that is denoted by an immutable object.

对此也有疑问:

  • How could I explain this unexpected behavior of my Scheme code?
  • Difference between '(()) and (cons null null)

这篇关于意外的数据持久性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆