将对象参数传递给宏时遇到错误。我必须引用这个论点,把它放在一个列表中,还是不引用它?
我希望使用Clozure Common Lisp使用读写锁来并行生成和运行多个进程,以控制数据输出到另一个进程。 with-write-lock是一个宏,等待给定的锁可用于写访问,然后在保持锁的情况下执行其主体。但是,无论我如何尝试将锁传递给with-write-lock,我都会收到错误。我想我遇到了麻烦,因为我无法理解如何将锁定对象传递给with-write-lock宏。如果我将锁绑定到符号,我会得到解构错误:
(let ((l (make-read-write-lock)))
(with-write-lock l (1+ 1)))
==>
> Error: L can't be destructured against the lambda list (LOCK), because it is not a proper list.
在执行Listener(4)的过程中执行:(:INTERNAL CCL :: NX1-COMPILE-LAMBDA)。
但是如果我将调用make-read-write-lock作为带锁定参数传递给with-write-lock,那么我得到一个未声明的自由变量错误:
(with-write-lock (make-read-write-lock) (1+ 1))
==>
;Compiler warnings for "/Users/frank/Documents/Lisp/threaded/act-parallel.lisp" :
;In an anonymous lambda form at position 18: Undeclared free variable MAKE-READ-WRITE-LOCK
错误:未绑定变量:MAKE-READ-WRITE-LOCK 执行时:#,在进程Listener(4)中执行。
我失败了,因为我误解了如何将一个对象传递给一个宏,或者我是否会出错,因为或者更具体的写入锁定?
这是Clozure Common Lisp(macros.lisp)附带的with-write-lock宏:
(defmacro with-write-lock ((lock) &body body)
(let* ((locked (gensym))
(p (gensym)))
`(with-lock-context
(let* ((,locked (make-lock-acquisition))
(,p ,lock))
(declare (dynamic-extent ,locked))
(unwind-protect
(progn
(write-lock-rwlock ,p ,locked)
,@body)
(when (lock-acquisition.status ,locked) (unlock-rwlock ,p)))))))
答案 0 :(得分:3)
该宏的lambda列表正在解构其参数。
((lock) &body body)
意味着它希望第一个参数作为包含锁定然后是正文形式的列表。这是CL中非常标准的宏参数列表,您可以像这样使用它:
(with-write-lock (lock)
..... body forms ....)
所以你的例子就是
(let ((l (make-read-write-lock)))
(with-write-lock (l) (1+ 1)))
和
(with-write-lock ((make-read-write-lock)) (1+ 1))
分别。注意第一个参数周围的额外数据。
对于类似的宏,请参阅with-open-file
或destructuring-bind
(with-open-file ("path/to/file" :open :args)
.... body ...)
(destructuring-bind (one two three) '(1 2 3)
.... body forms ...)