内部操纵的setdelayed会产生一个评估循环。为什么?

时间:2011-06-10 13:18:52

标签: wolfram-mathematica

为什么这样:

Manipulate[test[a_] := 2*b; test[c], {b, 0, 1}, {c, 0, 1}]

变成评估循环? Manipulateb更改时,c不应评估吗?

2 个答案:

答案 0 :(得分:7)

要以最小的更改来解决问题,请执行

Manipulate[
test[a_] := 2*b;
test[c], {b, 0, 1}, {c, 0, 1},
TrackedSymbols \[Rule] {b, c}]

代替(即添加TrackedSymbols告诉Mathematica要跟踪更改的内容)。

答案 1 :(得分:6)

是的,Manipulate会在bc更改时重新评估,但如果test发生更改,则test会重新评估每次这些值中的任何一个发生变化时都会分配因此,无休止的重新评估循环。

作为一项规则,应避免在ManipulateDynamic等构造的显示表达式中产生副作用,以避免评估循环,竞争条件和其他令人惊讶的行为。在本案例中,我建议删除b中对test的隐式依赖,并在Manipulate之外提升其定义:

test[b_, c_] := 2*b; Manipulate[test[b, c], {b, 0, 1}, {c, 0, 1}]

在实际应用中,这种简单的重构可能存在障碍 - 但关键是要从动态表达式中删除:=