我正在尝试对具有不同数量参数的不同函数进行循环。变量是在循环内的运行时创建的,我想在每次迭代中使用eval来使用变量:symbol实例化Struct。但是,我无法执行此操作,因为eval仅在全局范围内有效。这是适用的情况的MWE:
function f1(x); return x; end
function f2(x1,x2); return x1+x2; end
handles = [f1,f2]
args =[:(x1),:(x1,x2)]
x1 = 1; x2 = 1;
for (i,f) in enumerate(handles)
params = eval(args[i])
@show f(params...)
end
f(params...) = 1
f(params...) = 2
但是,如果我在循环中移动变量定义(这是我真正想要的),则在重新启动Julia清除工作区后它将无法工作。
function f1(x); return x; end
function f2(x1,x2); return x1+x2; end
handles = [f1,f2]
args =[:(x1),:(x1,x2)]
for (i,f) in enumerate(handles)
x1 = 1; x2 = 1;
params = eval(args[i])
@show f(params...)
end
ERROR: UndefVarError: x1 not defined
我已经尝试了几个答案,例如这个,但是我似乎无法使它起作用。我可以编写一个使用[x1,x2]的自定义调度函数,并使用正确的参数调用f1或f2。但是,仍然有什么方法可以通过eval或替代的优雅解决方案来做到这一点?
编辑:这是我要在代码中尝试做的更多详细信息。我为每种算法都有一个配置结构,在这种情况下,我想事先定义它需要的参数
KMF_config = AlgConfig(
name = "KMF",
constructor = KMC.KMF,
parameters = :(mu,N,L,p),
fit = KMC.fit!)
MF_config = AlgConfig(
name = "MF",
constructor = KMC.MF,
parameters = :(mu,N,L),
fit = KMC.fit!)
alg_config_list = [KMF_config, MF_config]
for (i,alg_config) in enumerate(alg_config_list)
mu,N,L,p,A,B,C,D,data = gen_vars() #this returns a bunch of variables that are used in different algorithms
method = alg_config.constructor(eval(method.parameters)...)
method.fit(data)
end
一种可能的解决方案是让一个函数接受所有变量和方法,并根据method.name返回一个带有变量子集的元组。但是我不确定这是否是最好的方法。
这是一种使用多个调度而不是的方法eval
:
run_a(x, y) = x + 10*y
run_b(x, y, z) = x + 10*y + 100*z
extract(p, ::typeof(run_a)) = (p.x, p.y)
extract(p, ::typeof(run_b)) = (p.x, p.y, p.z)
genvars() = (x=1, y=2, z=3)
function doall()
todo = [
run_a,
run_b,
]
for runalg in todo
v = genvars()
p = extract(v, runalg)
@show runalg(p...)
end
end
在您的例子中,你将取代run_a
并run_b
与KMC.KMF
和KMC.MF
。
编辑:清理示例以避免您的示例中不存在的结构。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句