我希望能够利用元编程回答这个问题,但是for循环的作用域规则导致我的变量不能在最上层(REPL)的作用域中被定义:
for x = [:A1, :A2]
@eval x = rand(2,2)
end
我知道可能有一种简单的方法来解决这个问题,但是我的周五晚上的大脑想不出来。你们其中有没有元编程专家能帮我找到一个简洁的解决方案呢?(我知道宏可能会在转义时起作用,但我正在尝试想出更短的东西)
我希望能够利用元编程回答这个问题,但是for循环的作用域规则导致我的变量不能在最上层(REPL)的作用域中被定义:
for x = [:A1, :A2]
@eval x = rand(2,2)
end
我知道可能有一种简单的方法来解决这个问题,但是我的周五晚上的大脑想不出来。你们其中有没有元编程专家能帮我找到一个简洁的解决方案呢?(我知道宏可能会在转义时起作用,但我正在尝试想出更短的东西)
如果您只想在全局作用域中定义变量,那么您只是忘了加一个$
:
for x = [:A1, :A2]
@eval $x = rand(2,2)
end
但是@eval
始终在顶层评估,即使将其放置在函数内部。如果您想在函数作用域中定义变量,则需要将整个函数放入@eval
中,构造代码块,并将其插值到函数中:
@eval function f()
...
$([:($x = rand(2, 2)) for x in [:A1, :A2]]...)
...
end
这段代码可以很容易地改写成宏形式(但是这时需要使用 esc
)。
@eval begin $([:($x = rand(2,2)) for x in [:B1,:B2]]...) end
或者 eval(Expr(:block, [:($x = rand(2,2)) for x in [:B1,:B2]]...))
才能实现。但我不确定这样做有什么意义,因为即使将其放在函数内部,它仍会在全局范围内定义变量。如果这正是你想要的,那么我认为我的第一个示例看起来更好一些。 - simonster
for x=1:100
然后呢?变量名如何可以通过编程方式生成? - rickhg12hsfor k=1:10 my_sym = symbol("A"*string(k)); @eval $my_sym = rand(2,2) end
(此处显示生成A1到A10。) - rickhg12hs