You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lisp中酒店程序宾客列表为何持续重置?技术咨询

解决宾客列表重置问题 & 未实现功能的思路

一、宾客列表自行重置的原因与修复方案

你当前用(get _name 'nbrguest)这类方式存储宾客数据,本质是给符号对象绑定临时属性——这种存储是会话级别的,一旦Lisp会话重启、符号被回收或重新定义,之前的宾客数据就会丢失,看起来就像“自行重置”了。

修复方案:用全局容器持久化宾客数据

我们可以改用全局哈希表(推荐)或者列表来存储所有宾客信息,让数据能在函数调用、甚至会话重启后(配合文件持久化的话)稳定保留。

修改你的代码:

  1. 先定义全局哈希表存宾客:
(defvar *guests* (make-hash-table :test #'equal)
  "全局哈希表,存储所有宾客信息,键是宾客姓名,值是包含各项属性的属性列表")
  1. 重写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))
  1. 新增查询宾客信息的辅助函数:
(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 02:23:09