Lisp中酒店程序宾客列表为何持续重置?技术咨询
解决宾客列表重置问题 & 未实现功能的思路
一、宾客列表自行重置的原因与修复方案
你当前用(get _name 'nbrguest)这类方式存储宾客数据,本质是给符号对象绑定临时属性——这种存储是会话级别的,一旦Lisp会话重启、符号被回收或重新定义,之前的宾客数据就会丢失,看起来就像“自行重置”了。
修复方案:用全局容器持久化宾客数据
我们可以改用全局哈希表(推荐)或者列表来存储所有宾客信息,让数据能在函数调用、甚至会话重启后(配合文件持久化的话)稳定保留。
修改你的代码:
- 先定义全局哈希表存宾客:
(defvar *guests* (make-hash-table :test #'equal) "全局哈希表,存储所有宾客信息,键是宾客姓名,值是包含各项属性的属性列表")
- 重写
guest函数,把数据存入哈希表:
(defun guest (_name _nbrguest _phone _duration _price _discount) (setf (gethash _name *guests*) (list :nbrguest _nbrguest :phone _phone :duration _duration :price _price :discount _discount)) (format t "宾客 ~a 已成功添加/更新~%" _name))
- 新增查询宾客信息的辅助函数:
(defun get-guest (_name) (multiple-value-bind (info exists) (gethash _name *guests*) (if exists info (format t "未找到宾客 ~a~%" _name))))
修改后,宾客数据会稳定存在全局哈希表*guests*里,除非你主动清空哈希表,否则不会再自行重置。
二、未实现功能的通用实现思路
虽然你没说明具体是哪两个功能,但基于酒店程序的常见需求,给你几个典型场景的实现参考:
场景1:列出所有宾客
(defun list-all-guests () (format t "=== 宾客列表 ===~%") (maphash (lambda (name info) (format t "姓名: ~a | 入住人数: ~a | 联系电话: ~a | 入住时长: ~a | 原价: ~a | 折扣(%): ~a~%" name (getf info :nbrguest) (getf info :phone) (getf info :duration) (getf info :price) (getf info :discount))) *guests*) (format t "=== 列表结束 ===~%"))
场景2:计算宾客最终应付金额
(defun calculate-final-price (_name) (multiple-value-bind (info exists) (gethash _name *guests*) (if exists (let* ((original-price (getf info :price)) (discount-rate (/ (getf info :discount) 100)) (final-price (* original-price (- 1 discount-rate)))) (format t "宾客 ~a 的最终应付金额: ~a~%" _name final-price) final-price) (format t "未找到宾客 ~a~%" _name))))
场景3:删除指定宾客
(defun delete-guest (_name) (if (remhash _name *guests*) (format t "宾客 ~a 已删除~%" _name) (format t "未找到宾客 ~a~%" _name)))
额外进阶提示
如果需要跨会话持久化数据(比如关闭Lisp后再打开还能看到宾客列表),可以添加文件读写功能:
;; 保存宾客数据到文件 (defun save-guests-to-file (filename) (with-open-file (out filename :direction :output :if-exists :supersede) (let ((guests-list '())) (maphash (lambda (k v) (push (cons k v) guests-list)) *guests*) (print guests-list out)))) ;; 从文件加载宾客数据 (defun load-guests-from-file (filename) (with-open-file (in filename :direction :input) (let ((guests-list (read in))) (clrhash *guests*) (dolist (guest guests-list) (setf (gethash (car guest) *guests*) (cdr guest))))))
内容的提问来源于stack exchange,提问作者jakHunter
相关产品推荐
相关产品推荐

