类中的lisp文件指针

类中的lisp文件指针,lisp,class-design,common-lisp,clos,Lisp,Class Design,Common Lisp,Clos,我在理解CLOS处理类内文件访问的方式时遇到了一个问题。在C++中,我可以做到这一点: class Foo { Foo (string filename); // opens the file (my_file) requested by the filename ~Foo (); // close the file FILE * my_file; // a persistent file-handle DataStruct my_data; // some d

我在理解CLOS处理类内文件访问的方式时遇到了一个问题。在C++中,我可以做到这一点:

class Foo {
   Foo (string filename);  // opens the file (my_file) requested by the filename
   ~Foo ();  // close the file

   FILE * my_file;  // a persistent file-handle
   DataStruct my_data;  // some data

   void ParseData ();  // will perform some function on the file and populate my_data
   DataStruct * GetData () { return &my_data; }  // accessor to the data
};
我想指出的是,prastata()将被多次调用,每次都会从文件中解析一个新的数据块,并且我的_数据将被更改

我尝试在CLOS中执行相同的技巧-创建所有通用方法来解析数据、加载文件、读取标题等,以及我拥有的类定义:

(defclass data-file ()
  ((filename :initarg :filename :accessor filename)
   (file :accessor file)
   (frame :accessor frame)))

在“构造函数”(即初始化实例)中,我打开文件,就像我的C++习语一样。然后我可以访问数据,并且可以像以前一样解析数据。但是,有人告诉我,使用“析构函数”或(finalize)方法关闭文件不是处理这种情况的惯用CLOS,因为我需要文件存在,以便可以在数据文件方法之外访问它


我将定义一个函数,它加载一个数据文件,然后用它的数据执行一系列分析,然后希望关闭它。做这件事的方法是什么?(我假设一个宏或某种类型的闭包可以在这里工作,但我对lisp方法不太熟悉,无法决定需要什么或如何实现它)。

一个选项是将流作为插槽而不是文件名,然后使用-OPEN-FILE对其进行范围限定:

(with-open-file (stream file)
  (let ((foo (make-instance 'foo :stream stream)))
    (frob foo)
    (...other processing of foo...)))

然后您的流将自动关闭。

我想我倾向于创建只存储完整权威数据的类(您称之为DataStruct?)

“加载+存储另一个类”并不需要特殊的类。另外,这种方式有一个不言而喻的不变量,即我的_数据将我的_文件的数据保存到当前的seek位置,这在我看来有点奇怪

换句话说,富是做什么的?给定一个文件名,它将加载数据,并提供一个数据结构。对我来说,这听起来像个函数。如果需要在线程中运行它,或者在加载记录之间触发事件,则类是在C++中自然完成的类,但是对于Lisp中的那些类,您不需要类。 另外,请记住,在CLO中使用泛型方法不需要使用DEFCLASS


我不知道数据的结构是什么,但在类似的情况下,我创建了一个parse one chunk函数,它接受一个流并返回一条记录,然后在一个打开的文件中的循环内创建一个完整的Foo实例。如果在具有打开的文件扩展的范围之外永远不需要流,那么您就不必担心关闭它。

我在解析其中一些内容时遇到了困难,不过还是要感谢您提供的见解。确实,Foo加载一个文件并返回一个数据结构,但它也保存文件指针。如果文件在读取某些数据时被关闭,我将需要寻找新的位置——用每个新的数据帧更新文件指针。我从您的评论中了解到,与其使用单个对象来操作文件流并解析数据,不如创建一个对象,该对象可以接受给定的文件流进行数据解析,并在其他地方管理文件和流。这是正确的吗?我想我对你的评论同样感到困惑。“创建一个可以接受给定文件流进行数据解析的对象”->当然,这个“对象”我称之为“函数”。:-)我真的不明白“Foo类”背后的目的。没有继承权。它有一个输入、一个输出、一个临时文件,以及一些在开始、中间和结束时运行的代码。在我的世界里,它描述的是一个函数,而不是一个类。但是我不完全理解上下文。肯:说得好。我在学习形成函数/类的过程中陷入了一个特殊的套路,所以我很欣赏这种见解。在这种情况下,除了DataStruct之外,没有理由创建一个对象来保存“权威数据”,并编写函数来执行围绕它的流操作