首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >setf表格的评价

setf表格的评价
EN

Stack Overflow用户
提问于 2017-02-18 19:02:10
回答 1查看 94关注 0票数 0

这个问题是关于Common setf宏的,以及它如何评估它的参数形式(和子表单)--也就是说,只有当它们出现不止一次时,它们才会出现一次。(这也是对Using get-setf-expansion评论中给出的一个例子的部分跟进。)

代码语言:javascript
复制
;create a list of two hash tables
* (defparameter hts (list (make-hash-table) (make-hash-table)))
HTS
* hts
(#<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>
 #<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>)

;define a function that swaps the position of the two hash tables
* (defun next-ht (hts) 
    (rotatef (first hts) (second hts))
    (second hts))
NEXT-HT

交换:

代码语言:javascript
复制
;now do a swap to verify it works
* (next-ht hts)
#<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>
* hts
(#<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>
 #<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>)

;and swap them back
* (next-ht hts)
#<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>
* hts
(#<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>
 #<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>)

进一步测试:

代码语言:javascript
复制
;then set different values for a key in each table
* (setf (gethash 0 (first hts)) 11)
11
* (setf (gethash 0 (second hts)) 22)
22
* hts
(#<HASH-TABLE :TEST EQL :COUNT 1 {1007F76CB3}>
 #<HASH-TABLE :TEST EQL :COUNT 1 {1007F77103}>)

;finally execute a setf with a swapping side-effect
* (setf (gethash 0 (next-ht hts)) (1+ (gethash 0 (next-ht hts))))
23

;but it looks like hts has been swapped twice
;back to its original state
* hts
(#<HASH-TABLE :TEST EQL :COUNT 1 {1007F76CB3}>
 #<HASH-TABLE :TEST EQL :COUNT 1 {1007F77103}>)

;also, where did the initial value of 11 go?
* (gethash 0 (first hts))
23
T
* (gethash 0 (second hts))
22
T
*

有人能澄清发生了什么事吗?另外,有副作用的setf表达式的含义是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-18 19:49:23

为什么不宏展开setf表单呢?在这里,LispWorks:

代码语言:javascript
复制
CL-USER 32 > (pprint (macroexpand '(setf (gethash 0 (next-ht hts))
                                         (1+ (gethash 0 (next-ht hts))))))

(LET* ((#:|key1014| 0)
       (#:|table1015| (NEXT-HT HTS))
       (#:|default1016| NIL)
       (#:|store1017| (1+ (GETHASH 0 (NEXT-HT HTS)))))
  (SYSTEM::%PUTHASH #:|key1014| #:|table1015| #:|store1017|))

是干什么的呢?

  • 得到键值
  • 获取哈希表,调用NEXT-HT
  • 获取默认值,而不是使用
  • 获取新值,调用NEXT-HT
  • 使用一些特定于实现的方式将新的键/值存储到哈希表中。

所以很明显,NEXT-HT被叫了两次。

什么是粗(!)它背后的概念模型?

  • setf将检查第一个表达式。
  • 那是什么?哦,是gethash,让我为它设置setter表单。
  • 然后,setter表单将评估第一个表单中所需的子表单。
  • 然后,它将计算新值。
  • 将使用这些参数调用setter运算符。

示例:

代码语言:javascript
复制
CL-USER 62 > (setf (gethash (print 0)
                            (print (next-ht hts))
                            (print 1))
                   (print (1+ (print (gethash 0
                                              (print (next-ht hts))
                                              2)))))

0 
#<EQL Hash Table{1} 402000137B> 
1 
#<EQL Hash Table{0} 4020001573> 
2 
3 
3   ; return value
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42319416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档