检查lisp中是否存在关键字参数

Bri*_*lli 2 lisp common-lisp

我正在尝试编写一个函数,通过以下方式将关键字参数传递给函数

 (defun hyphenate (string &key upper lower)
  (do ((s (cdr (coerce string 'list)) (cdr s))
       (acc (string (char string 0))))
      ((null s) (cond
                 (lower (string-downcase acc))
                 (t (string-upcase acc))))
     (cond
      ((upper-case-p (car s)) (setf acc (concatenate 'string
                                                     (concatenate 'string acc "-")
                                                     (string (car s)))))
      (t (setf acc (concatenate 'string acc (string (car s))))))))) 
Run Code Online (Sandbox Code Playgroud)

基本上,如果函数接收关键字upper,它将调用string-upcase,如果它接收到key down,它将执行string-downcase.

我只是不知道在我的函数中测试这些参数的适当方法是什么.我不想将它们绑定到一个值.我只想这样打电话给他们

(连字符"jobPostings":上)

如何在函数调用中检查是否存在:upper?它一直告诉我有一个"未成对的关键字传递给连字符"

Rai*_*wig 6

关键字作为参数和关键字参数是两个不同的东西.关键字参数是命名参数.它们分为两个部分:名称.

像这样:

CL-USER 1 > (defun hyphenate (string &key upper lower) (list string upper lower))
HYPHENATE
Run Code Online (Sandbox Code Playgroud)

您需要提供名称和值.请注意,未传入的关键字参数的值为NIL.

CL-USER 2 > (hyphenate "foo" :upper t)
("foo" T NIL)
Run Code Online (Sandbox Code Playgroud)

将其与可选参数进行比较:

CL-USER 3 > (defun hyphenate (string &optional case) (list string case))
HYPHENATE
Run Code Online (Sandbox Code Playgroud)

现在,您只需要提供可选参数,该参数可以是符号:upper.

CL-USER 4 > (hyphenate "foo" :upper)
("foo" :UPPER)
Run Code Online (Sandbox Code Playgroud)

或者您使用命名关键字参数,在其中传入案例符号:

CL-USER 5 > (defun hyphenate (string &key case) (list string case))
HYPHENATE
Run Code Online (Sandbox Code Playgroud)

同样,作为两个项目:名称和值:

CL-USER 6 > (hyphenate "foo" :case :upper)
("foo" :UPPER)
Run Code Online (Sandbox Code Playgroud)

关于你的功能的一些评论:

  • 如果检查谓词,请使用IF,而不是COND

  • 您正在迭代字符串并首先将其转换为字符串.通常,您将使用索引迭代字符串.

  • 你是在DO循环中一遍又一遍地将单个字符连接成一个字符串.那很难看.如果您已经使用输入列表,为什么不使用输出列表并在退出时将其转换回字符串?

如果您希望继续使用列表,则需要映射列表.

(defun hyphenate (string  &key (case :upper))
  (map 'string
       (if (eq case :upper) #'char-upcase #'char-downcase)
       (destructuring-bind (start . rest)
           (coerce string 'list)
         (cons start
               (mapcan (lambda (char)
                         (if (upper-case-p char)
                             (list #\- char)
                           (list char)))
                       rest)))))
Run Code Online (Sandbox Code Playgroud)

MAPCAN插入必要的连字符.外部MAP转换大小写并返回一个字符串.