common-lisp - 为什么在 `let` 中调用 `make-instance` 的工作方式不同?
问题描述
我正在探索 Common Lisp 语法的一些可能性,并且我想在某些情况下创建一个:around
方法make-instance
来返回一些任意值。为简单起见nil
,当我没有传递所需的参数时,就让它成为吧。它有效,但在调用 let 时无效:
(defclass foo ()
((bar :initarg := :initform '())))
(defmethod make-instance :around ((type (eql 'foo)) &key =)
(if (not =) nil (call-next-method)))
(print (make-instance 'foo)) ;; => NIL
(print (let ((x (make-instance 'foo))) x)) ;; => #<FOO {10037EEDF3}>
有人可以解释这种情况吗?为什么呢?SBCL 是试图变得聪明,还是实际上是标准的事情?我知道我可以通过使用 apply 来解决它:
(print (let ((x (apply #'make-instance (list 'foo)))) x)) ;; => NIL
但我不想依赖这种解决方法。实际上,我可以为此使用常规功能,这没关系,但我想了解它为什么会这样工作以及是否可以禁用这种行为。
解决方案
看起来像是MAKE-INSTANCE
SBCL(-> CTOR)中常量类名的优化尝试之一......
这似乎有效:
(defmethod make-instance :around ((class (eql (find-class 'foo)))
&rest initargs
&key =
&allow-other-keys)
(declare (ignorable initargs))
(if (not =) nil (call-next-method)))
但询问 SBCL 专家或提交错误报告可能很有用......
推荐阅读
- python - 用Anaconda下载了模块,但在Pycharm环境中找不到?
- python-3.x - 如何解析此页面中的表格?
- javascript - Javascript 自动点击在 hi5/tagged 网站上不起作用
- java - 反正有没有从java调用像Vision这样的iOS框架?
- swift - 如何在不四舍五入的情况下将 NSString 转换为浮点数?
- perl - 即使我没有从文件中读取有问题的数据,Perl 也会警告无效编码
- windows - HostedNetwork 获取当前客户端数量
- docker - 如何将 Yourkit 包含在 neo4j docker 映像中?
- python - 有没有办法用 python 更改 dash 上的日间股票图,以便不绘制 16:00 之后和 9:30 之前的时间?
- sql-server - SQL Server 架构 VS 数据库架构