首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >闭包中的不一致性:宏和IllegalArgumentException中的函数

闭包中的不一致性:宏和IllegalArgumentException中的函数
EN

Stack Overflow用户
提问于 2013-10-17 04:53:38
回答 2查看 662关注 0票数 11

以下两个在宏中使用函数的示例将导致计算结果没有错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(defmacro works []
  (let [f (fn [] 1)]
    `(~f)))
(works)
;; => 1

(defn my-nullary-fn []
  (fn [] 2))
(defmacro also-works []
  (let [f (my-nullary-fn)]
    `(~f)))
(also-works)
;; => 2

然而,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(defmacro does-not-work []
  (let [f (constantly 3)]
    `(~f)))
(does-not-work)

抛出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.IllegalArgumentException: No matching ctor found
for class clojure.core$constantly$fn__4051 

同样的,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(defn my-unary-fn [x]
  (fn [] x))
(defmacro also-does-not-work []
  (let [f (my-unary-fn 4)]
    `(~f)))
(also-does-not-work)

抛出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.IllegalArgumentException No matching ctor found
for class user$my_other_fn$fn__12802

可能是什么原因?fnmy-nullary-fnconstantlymy-unary-fn返回的函数对象之间是否有区别?

我正在运行Clojure 1.5.1。

CLJ-946可能是相关的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-18 06:46:48

看看clojure.lang.Compiler.ObjExpr#emitValue()。任何直接出现在代码中的实例对象(或在宏展开结果中生成的代码)都必须是:

  • 类型编译器知道如何实例化或发出对;或
  • 为它们的类型定义print-dup,在这种情况下编译器通过读取器发出对象实例化。

函数对象确实有一个print-dup实现,但它构造的读- version只调用函数类构造函数的0参数版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(print-dup (fn [] 1) *out*)
;; #=(user$eval24491$fn__24492. )
(let [x 1] (print-dup (fn [] x) *out*))
;; #=(user$eval24497$fn__24498. )

Clojure闭包是通过函数类实现的,函数类接受它们的闭包变量值作为构造函数参数。因此:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(let [f (fn [] 1)] (eval `(~f)))
;; 1
(let [x 1, f (fn [] x)] (eval `(~f)))
;; IllegalArgumentException No matching ctor found ...

所以现在您知道了,并且知道了为什么要避免将函数对象直接插入到生成的代码中,即使它“工作”。

票数 7
EN

Stack Overflow用户

发布于 2013-10-17 06:56:35

请参阅此示例,该示例也会引发异常:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(defmacro does-also-not-work []
  (let [x 4
        f (fn [] x)]
    `(~f)))

constantly的结果一样,但与前两个示例不同的是,这里的f是一个闭包。显然,在宏扩展期间创建的闭包不会持续.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19427303

复制
相关文章
Python将字符串转换为列表
We can convert a string to list in Python using split() function.
全栈程序员站长
2022/09/06
6K0
python--练习--将字符串转成列表
a="alex" lic=[] for i in range(len(a)): lic.append(a[i]) print(lic)
py3study
2020/01/15
1.4K0
3-序列、列表、元组
序列就是一堆数据元素的集合,并对每个元素进行编号。在Python中,字符串、列表、元组都属于序列,他们都具有一些特定的操作,如索引、切片、相加、相乘、in、长度、最大值和最小值。
用户3106371
2018/09/12
7610
python split()函数使用拆分字符串 将字符串转化为列表
函数:split() Python中有split()和os.path.split()两个函数,具体作用如下: split():拆分字符串。通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list) os.path.split():按照路径将文件名和路径分割开 一、函数说明 1、split()函数 语法:str.split(str="",num=string.count(str))[n] 参数说明: str:   表示为分隔符,默认为空格,但是不能为空('')。若字符串中没有分隔符,则把整个字
程序员同行者
2018/06/22
6.2K0
python 字符串转列表,列表转字符串
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/144126.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/31
1.2K0
python 字符串转列表,列表转字符串
Python字符串,列表
字符串: 字符串的创建: 单引号, 双引号 ,三引号 <注意: 转义字符的使用> 字符串的特殊性: 索引 切片 连接 重复 成员操作符(in, not in)
py3study
2020/01/14
9790
Python将一个数逆序列放入列表中
小小科
2020/06/15
1.2K0
python字符串转化列表_Python列表到字符串的转换[通俗易懂]
Sometimes we want to convert the list to a string so that we can print it or log it for debugging purposes. In this tutorial, we will learn how to convert a list to string in a Python program.
全栈程序员站长
2022/08/25
2.7K0
python学习3-内置数据结构1-列表
lst = list(range(1,20))    #使用list把可迭代对象转换为列表
py3study
2020/01/10
1.1K0
for循环将字典添加到列表中出现覆盖前面数据的问题
我们可以看到上面的代码,我们通过for循环输入了3次不同的用户名和密码,并且添加到 user_list 的列表中,但是最终 user_list 打印了三次相同的数据
全栈程序员站长
2022/06/29
4.5K0
Python:将列表转为字符串的3种方法「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/141887.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/25
1.5K0
python的数与字符串
在python中我们现在有不同的版本现在有python2.7与python与3.0 要说他们的区别就在与输出的不同
py3study
2020/01/17
5150
将Sublime添加到鼠标右键
2、找到 HKEY_CLASSES_ROOT/*/shell 目录,在此目录下操作。
新码农
2020/03/05
3K0
用Python将一个列表分割成小列表
方法一 def list_of_groups(init_list, childern_list_len): ''' init_list为初始化的列表,childern_list_len初始化列表中的几个数据组成一个小列表 :param init_list: :param childern_list_len: :return: ''' list_of_group = zip(*(iter(init_list),) *childern_list_len)
py3study
2020/01/06
3.2K0
python: 将列表中的字符串 连接成一个 长路径
  今天实习公司分配了一个数据处理的任务。在将列表中的字符串连接成一个长路径时,我遇到了如下问题:
JNingWei
2018/09/28
2.9K0
Python 列表元素字符串转浮点
在网络爬虫或者读取文件中的数据时,很多时候读取出来的数值是字符串形式的,这些字符串形式的数据并不能用来作计算或者更深入的操作,因此我们需要把他们转换为数值的形式。
全栈程序员站长
2022/09/05
2.1K0
python3-列表与字符串
print(x) x3=tuple(x) print(x3) [1, 2, 5, 4, 3, 10, 20, [1, 2]] (1, 2, 5, 4, 3, 10, 20, [1, 2])
py3study
2020/01/06
6520
将Windows Terminal添加到鼠标右键
导读 非常实用的小技巧。 下载Windows Terminal图标,右键另存为。 [WindowsTerminal图标] 保存至'C:\Users\Administrator\AppData\Local\Terminal\Terminal.ico'。 win+R输入'regedit',打开注册表。 找到'HKEY_CLASSES_ROOT\Directory\Background\shell'目录,在此目录下操作。 新建项'wt',双击右边'默认',更改右键文字显示内容'Windows Terminal H
新码农
2020/08/05
3.6K0
将Windows Terminal添加到鼠标右键
Python将字符串转为字典
在工作中我们经常会遇到数据类型之间的互转的问题,而通常我们请求一些API借口返回的结果就是字符串,但是格式是Json的,在Python中转为字典是最易处理的,所以这里记录一下在Python下把字符串转为字典的三种方法。
后场技术
2020/09/03
4.4K0
Python将字符串转为字典
Python 生成随机数_python 随机字符串
python中生成随机数主要使用random模块和numpy库中的random函数。
全栈程序员站长
2022/11/10
1.6K0

相似问题

Python 3-如何将字符串转换为字典列表

11

Python 3-从列表到精确字符串(如列表)

10

将字符串添加到Python列表

10

Python -如何将随机数添加到列表中?

30

Python 3-基于字符串的字典搜索列表

24
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文