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
相关产品推荐
相关产品推荐

