Julia自定义宏运行报no method matching iterate(::Expr)如何解决?
报错原因
Julia 宏接收到的所有输入参数都是语法树(Expr类型对象),你调用时写的{1,2}不会被直接解析为集合,而是会作为head为:braces的Expr对象传入宏内。你直接将这个Expr对象传给map,map需要对可迭代对象做遍历,而Expr本身没有实现迭代器协议,就触发了这个报错。
额外说明:Julia 原生没有{}作为集合字面量的语法,正常代码里写{1,2}本身也不是合法的集合字面量,只会被解析为Expr。
解决方案
根据你的使用场景选对应写法即可:
场景1:需要在宏展开阶段就执行map处理传入的常量集合
直接取出Expr的args字段,这个字段存储了花括号内的所有元素:
macro superM(arg, argc) # 提取花括号内的元素列表 items = argc.args # 展开阶段直接执行map map(foo, items) end
场景2:需要在代码运行阶段才执行map(比如传的参数包含变量)
宏要返回map调用的表达式,放到运行期执行:
macro superM(arg, argc) items = argc.args # 生成运行期执行的map调用表达式,这里默认打包为数组,可根据需要改成Set、Tuple等 return :( map(foo, $items) ) end
调用验证
两种场景下你原来的调用写法都可以正常执行:
@superM test {1,2}
如果不想自定义花括号语法,也可以直接用Julia原生的数组字面量传参,写法更规范,也不需要额外解析Expr:
# 宏调用改传数组 @superM test [1,2] # 宏内可以直接把参数插到表达式里 macro superM(arg, argc) return :( map(foo, $argc) ) end
内容的提问来源于stack exchange,提问作者ahm5
相关产品推荐
相关产品推荐

