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

Racket中从文本文件列表移除元素失败问题求助

问题描述

我尝试从列表中移除元素时遇到问题:该列表此前通过call-with-output-file写入文本文件,现使用call-with-input-file读取,读取后列表形式为("a" "b" "c"),计划用remove函数移除元素。

代码:
读取/写入:

(define lst
    (call-with-input-file "todo.txt"
      (lambda (des)
        (read des))))

(call-with-output-file "todo.txt" #:exists 'update
       (lambda (out)
         (write lst out)))

移除逻辑:

[(equal? action "remove todo")
     (display (~a "Choose an ToDo to remove:\n" lst "\n"))
     (remove (string-trim (read-line)) lst)
     (call-with-output-file "todo.txt" #:exists 'update
       (lambda (out)
         (write lst out)))
     (display "Removed.")]))

预期行为:
程序将移除元素后的新列表写入文本文件。

实际行为:
程序用原列表覆盖文件,未执行删除操作且无报错。


解决方案

核心问题是:Racket中的remove函数不会修改原列表,它会返回一个移除目标元素后的新列表。你当前仅调用了remove但未将返回结果赋值给lst,导致原列表变量完全没有更新,写入文件的自然还是初始列表。

修改移除逻辑部分,用set!将remove的结果重新绑定到lst:

[(equal? action "remove todo")
     (display (~a "Choose an ToDo to remove:\n" lst "\n"))
     ; 关键:用set!更新lst为移除元素后的新列表
     (set! lst (remove (string-trim (read-line)) lst))
     (call-with-output-file "todo.txt" #:exists 'update
       (lambda (out)
         (write lst out)))
     (display "Removed.")]))

补充说明

  • Racket默认变量是不可变的,必须通过set!来重新绑定变量指向新的列表对象。
  • remove默认使用equal?比较元素,确保用户输入经string-trim处理后能和列表中的字符串精确匹配。如果有大小写、特殊字符等匹配需求,可以自定义比较函数(比如用remove*配合string-ci=?实现大小写不敏感匹配)。

内容的提问来源于stack exchange,提问作者Firstmine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 21:16:03