我对 common lisp 相当陌生,并且一直在做练习来进入它。
我在 Windows 10 上的 wsl2 上使用 debian。
我有 sbcl 2.1.1 和 Quicklisp
这是我尝试加载的文件
(defpackage :lillys-lasagna-leftovers
(:use :cl)
(:export
:preparation-time
:remaining-minutes-in-oven
:split-leftovers))
(in-package :lillys-lasagna-leftovers)
(defun preparation-time (&rest rest)
(* 19 (length rest)))
(defun remaining-minutes-in-oven (&optional (opt :normal opt-provided))
(if opt-provided (cond
((eql opt :shorter) 337)
((eql opt :very-short) 137)
((eql opt :longer) 437)
((eql opt :very-long) 537)
(t nil))
opt))
Run Code Online (Sandbox Code Playgroud)
除了第二个函数不正确可能出现的问题之外。我尝试通过两种方式加载上述文件
通过输入 sbcl 并使用
(load "test-file-name")
(preparation-time 1 2 3)
Run Code Online (Sandbox Code Playgroud)
通过将文件加载到 sbcl
sbcl --load "test-file-name"
(preparation-time 1 2 3)
Run Code Online (Sandbox Code Playgroud)
在这两种情况下我都得到
CL-USER(1): (preparation-time)
; in: PREPARATION-TIME
; (PREPARATION-TIME)
;
; caught STYLE-WARNING:
; undefined function: COMMON-LISP-USER::PREPARATION-TIME
;
; compilation unit finished
; Undefined function:
; PREPARATION-TIME
; caught 1 STYLE-WARNING condition
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我想要一种可以在本地测试我的代码的方法。
当您编写不带包前缀的符号时,阅读器将使用当前包(以及其他阅读器设置)来决定它引用的符号。启动 SBCL 时,当前包名为 CL-USER。
PREPARATION-TIME您的函数由名为 的包中的字符串命名LILLYS-LASAGNA-LEFTOVERS。如果你在 CL-USER 包中,并且你想引用它,你可以这样做:
(lillys-lasagna-leftovers::preparation-time 1 2 3)- 这将适用于符号,无论其外部状态如何(lillys-lasagna-leftovers:preparation-time 1 2 3)- 这种只有一个冒号的语法有效,因为您曾经:export将符号设为外部如果您想在preparation-time没有包前缀的情况下引用,有以下几种选择:
(use-package :lilys-lasagna-leftovers)将使当前包继承所有外部符号,其中包括preparation-time- 如果已经可以通过相同名称访问不同的非 eq 符号,则这可能会失败(import 'lilys-lasagna-leftovers:preparation)将使该符号出现在当前包中,因此可以在没有前缀的情况下引用它 - 如果已经可以通过相同名称访问不同的非 eq 符号,则这可能会失败(shadowing-import 'lilys-lasagna-leftovers:preparation)将使该符号出现在当前包中,并另外覆盖任何以前可访问的同名符号(in-package :lilys-lasagna-leftovers)将更改的值*package*,因此没有包前缀的符号查找是相对于您的包的在所有这些选项中,如果我正在从事这个项目,我很可能会使用in-package. 其他选项也有其最合适的用途,但您通常可以从需要开始in-package并在需要时继续进行其他操作。