我将命令行参数传递给我的 Lisp 程序,当它们到达我的 main 函数时,它们的格式如下:
("1 1 1" "dot" "2 2 2")
我有一个点函数(它接受两个向量作为参数)并想直接从参数调用它,但这是不可能的,因为像 (funcall (第二个参数)...) 这样的东西接收
"dot"
而不是dot
作为函数名称。
我尝试了此功能的变体:
(defun remove-quotes (s)
(setf (aref s 0) '""))
无济于事,然后才意识到引号并不是真正的字符串的一部分。有没有一种简单的方法可以做到这一点,或者我应该检查每个字符串然后调用适当的函数?
"1 1 1"
是一个由五个字符组成的字符串:1、空格、1、空格和 1。双引号不是字符串的一部分。
("1 1 1" "dot" "2 2 2")
是三个字符串的列表。
上面没有
"
字符。 "
用于分隔 s 表达式中的字符串。
如果您有点函数,您需要告诉我们它期望什么样的输入数据。
它需要两个数字列表吗?然后你必须将字符串
"1 1 1"
转换为数字列表。
(with-input-from-string (in "1 1 1")
(loop for data = (read in nil in)
until (eq data in)
collect data)))
要从字符串
DOT
中获取函数"dot"
,首先找到符号DOT
,然后获取其符号函数。
(symbol-function (find-symbol (string-upcase "dot")))
对于
find-symbol
,如果符号所在的特殊包中,可能还需要指定包。
将列表转换为向量是下一个构建块。
因此,您需要将函数的参数转换为向量(可能首先将它们转换为列表,如我上面所示)。然后你需要找到该函数(见上文)。如果您有函数和参数,那么您可以使用
FUNCALL
或 APPLY
(以更方便的方式)调用该函数。
这个问题有点不清楚,但据我了解,当给出列表
("1 1 1" "dot" "2 2 2")
作为输入来评估表达式 (dot "1 1 1" "2 2 2")
时,你想要的。在这种情况下,你可以这样做:
(defun apply-infix (arg1 f arg2)
(apply (intern (string-upcase f)) (list arg1 arg2)))
(defun apply-list-infix (lst)
(apply 'apply-infix lst))
(apply-list-infix '("1 1 1" "dot" "2 2 2"))
funcall
不接受字符串作为函数指示符。您需要给它一个符号。您可能想做的是:
string-upcase
)。intern
)。请注意,如果未根据函数名称所在的包设置 *package*
,则需要将包名称作为第二个参数提供给 intern
。例如(对于包
dot
中名为 cl-user
的函数:
(funcall (intern (string-upcase "dot") 'cl-user) ...)