明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2728|回复: 13

[经验] set和setq的区别和使用中的疑问

[复制链接]
发表于 2018-7-19 21:01:39 | 显示全部楼层 |阅读模式
本帖最后由 wujiguang 于 2018-7-19 23:18 编辑

《AutoLISP 语言程序设计 》第30页有句话是这样的。
(SET <符号表达式> <表达式>)
SET 和 SETQ 一样都是赋值函数,不同的是:
...
SET 是将<表达式>的值赋给<符号表达式>的值,而不是赋给符号本身;
...

(set (read "a") 5)  返回 5
(read "a")            返回 A
但是
(set A 5)              返回错误;
这时候必须使用
(setq a 5)              返回 5;

我的疑问是 (read "a") 返回的是个什么性质的东西,符号?为什么(set A 5)会报错,而(set (read "a") 5)  却不会报错。
为什么(set (read "a") 5)  中的第一个参数(read "a")返回了A,却没有计算符号A的值呢?  




发表于 2020-5-17 09:57:51 | 显示全部楼层
再补充
set可以批量交换变量而setq不行

;举例1
(setq a 1 b 2 c 3)
(mapcar 'set '(a b c) '(1 2 3)) ; 表
;返回值都一样是 1 2 3

;举例2
(setq l1 '(a b c) z1 '(1 2 3)
        l2 '(x y z) z2 '(7 8 9))

(mapcar 'set l1 z2 ) ; 变量l1(a b c)值z2(7 8 9)
(mapcar 'set l2 (mapcar 'eval l1)) ;拷贝l1(值z2)去变量l2(x y z)值='(7 8 9)
(mapcar 'set l1 z1 ) ;变量l1(a b c)值z1(1 2 3) 变量l1值='(1 2 3)

;举例3
(mapcar 'set l1 (reverse z1) ) ;也可以反转值

;举例4
;批量清理全局变量(a b c)
(mapcar '(lambda (x)(set x nil)) l1 )
;(NIL NIL NIL)

;清除(x y z)因为(a b c)已nil
(mapcar '(lambda (i j)(set i (eval j))) l2 l1 )
;x y z = nil nil nil


 楼主| 发表于 2018-7-20 09:21:30 | 显示全部楼层
自贡黄明儒 发表于 2018-7-20 08:11
Command: (set 'A 5)就不会出错了。

您好,我的疑问是 不理解set的操作逻辑。
(set 'A 5) 相当于 (set (qoute A) 5) ,set 函数是会让第一个表达式求值的,而qoute又恰是阻止求值的。我实在无法理解set函数的运算逻辑,在这里为什么set不会对(qoute A)的返回值A 进行求值呢?
跟我发帖的类似,set为什么不对(read "a")的返回值A进行求值呢?
发表于 2018-7-19 22:10:57 | 显示全部楼层
我也是新人 我說一下我理解的看法
SET 是将<表达式>的值赋给<符号表达式>的值,而不是赋给符号
這句話已經說的很明確了
(set (read "a") 5)  返回 5
(read "a") = <表达式>
a 不等於 <表达式> 所以nil

我是個新人說的 僅供參考 我只是看了一下你發的 解釋 感覺是這樣理解的
发表于 2018-7-19 23:28:37 | 显示全部楼层
发表于 2018-7-20 08:11:35 | 显示全部楼层
Command: (set 'A 5)就不会出错了。
发表于 2018-7-20 17:28:47 | 显示全部楼层
阻止求值,本身就是求值
发表于 2018-7-20 17:48:26 来自手机 | 显示全部楼层
记住用法就行了,究其本质的话,估计要用到汇编的概念。例如,变量名 A,变量地址(指针)  'A,变量的值100,被存储在不同的寄存器里,用来区分哪些1和0是指令,哪些1和0是数据。大致有堆,栈,自由区,静态区,常量空间等,估计是set和setq的第一参数就在不同的存储区,所以用法不同,纯属猜想没有证明。
发表于 2018-7-21 06:47:07 | 显示全部楼层
个人认为:LISP的精髓表现在SET和EVAL两个函数。其他编程语言没有类似的概念及功能。
 楼主| 发表于 2018-7-21 13:03:50 | 显示全部楼层
crtrccrt 发表于 2018-7-21 06:47
个人认为:LISP的精髓表现在SET和EVAL两个函数。其他编程语言没有类似的概念及功能。

我觉得还要加上 quote 这个函数,其他编程语言如 matlab python 都有eval函数,这个是比较常见的。
发表于 2020-3-25 11:38:42 | 显示全部楼层
yxp 发表于 2018-7-20 17:48
记住用法就行了,究其本质的话,估计要用到汇编的概念。例如,变量名 A,变量地址(指针)  'A,变量的值100 ...

太厉害了,竟然说的都对。od跟踪了一下,确实如此。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-5-18 03:52 , Processed in 0.163295 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表