lisp - LISP--传递一个结构组件,而不是组件的值
问题描述
我在 LISP 中传递结构组件时遇到问题。我想传递组件,而不是组件的值。
为了说明我的目标,假设我有一个结构实例,node
. 节点具有组件farmer
、fox
、goose
和straw
。我希望函数灵活,所以我可以将这些组件中的任何一个传递给函数。
(defun pass-comp (node object)
(setf object 1)
node)
(pass-comp (node (node-fox node))
(write (node-fox node))
—> 1
解决方案
在 Lisp 中,所有参数总是按值传递。如果要修改传递的结构的内容,可以通过指定要修改的内容来完成:
(defstruct node farmer fox goose straw)
(defparameter *node* (make-node :fox 3))
(defun change-slot (object slot-name new-value)
(setf (slot-value object slot-name) new-value))
(change-slot *node* 'fox 7)
(change-slot *node* 'goose 23)
*node*
==> #S(NODE :FARMER NIL :FOX 3 :GOOSE 23 :STRAW NIL)
请注意,即使该标准不需要slot-value
在 上运行
,
structure-object
上面的代码也适用于所有 CL 实现。
如果您希望您的代码符合要求,则应传递一个setter:
(defun change-slot (object setter new-value)
(funcall setter new-value object))
(change-slot *node* #'(setf node-farmer) 6)
*node*
==> #S(NODE :FARMER 6 :FOX 3 :GOOSE 23 :STRAW NIL)
唉,这也不能保证工作,因为:
写入槽的能力是由 setf 函数还是由 setf 扩展器实现的,这取决于实现。
因此,您需要创建自己的 setter:
(change-slot *node* (lambda (straw node) (setf (node-straw node) straw)) 11)
*node*
==> #S(NODE :FARMER 6 :FOX 3 :GOOSE 23 :STRAW 11)
推荐阅读
- python - 将 Python 生成器重写为异步
- c# - 如何正确使用视图或将表名重定向到第二个名称?
- php - Laravel 获取没有 n 个最新条目的条目
- kotlin - 如何正确初始化 ConstraintVerifier 以在 Kotlin 中测试 Optaplanner ConstraintStreams
- ionic-framework - 离子标题标题越过按钮
- swift - swift SceneKit计算节点角度
- python - 在 `dash_table.DataTable` 单元格中显示数组
- asp.net-core - 在 ASP.Net Core 3 中使用 Rabbitmq 的 RPC
- node.js - 获取 Google 访问令牌的问题
- postgresql - 在函数内部使用时选择查询输出错误值