我根据用户输入调用函数,但有些函数有两个参数,有些只有一个参数。代替在每个函数上使用&optional参数(并且从不使用它),有没有一种方法可以在参数的值为"NIL“时简单地不传递它?
这是一个交互式的虚构游戏,在游戏中,用户输入一些命令,这些命令被转换为函数调用。
(defun inputs (state)
(format *query-io* "> ")
(force-output *query-io*)
(let* ((entry (cl-ppcre:split "\\s+" (string-downcase (read-line *query-io*))))
(function (car entry))
(args (cdr entry)))
(if (valid-call function)
(funcall (symbol-function (read-from-string function))
state
args)
(progn
(format *query-io* "Sorry, I don't know the command '~a'~%~%" function)
(inputs state)))))如果用户输入是"equip sword",我需要调用函数"equip“来传递'("Sword")作为参数,但是如果用户输入是"status",我需要调用函数"status”而不是传递“args”,而不是将它们作为"NIL“传递。
发布于 2019-01-15 22:49:15
我认为您应该使用apply而不是funcall,使用find-symbol而不是read-from-string (这对security reasons来说实际上很重要!)和destructuring-bind而不是let*
(defun inputs (state)
(format *query-io* "> ")
(force-output *query-io*)
(destructuring-bind (command &rest args)
(cl-ppcre:split "\\s+" (string-downcase (read-line *query-io*)))
(if (valid-call command)
(apply (find-symbol command) state args)
(progn
(format *query-io* "Sorry, I don't know the command '~a'~%~%" command)
(inputs state)))))使用apply可以让您的命令接受任意数量的参数,而不是一个。
实际上,您的valid-call可能应该返回要调用的函数:
(let ((f (valid-call function)))
(if f
(apply f state args)
...)发布于 2019-01-15 23:48:25
您还可以使用简单的LOOP而不是递归调用:
(defun inputs (state)
(loop
(format *query-io* "> ")
(force-output *query-io*)
(let* ((entry (cl-ppcre:split "\\s+" (string-downcase (read-line *query-io*))))
(function (car entry))
(args (cdr entry)))
(when (valid-call function)
(apply (symbol-function (find-symbol function))
state
args)
(return))
(format *query-io* "Sorry, I don't know the command '~a'~%~%" function))))https://stackoverflow.com/questions/54200901
复制相似问题