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

P. *_*eca 2 wolfram-mathematica

为什么这样:

Manipulate[test[a_] := 2*b; test[c], {b, 0, 1}, {c, 0, 1}]
Run Code Online (Sandbox Code Playgroud)

变成评估循环?不应该Manipulate只评估何时bc改变?

acl*_*acl 7

要用最少的更改来解决问题,请执行

Manipulate[
test[a_] := 2*b;
test[c], {b, 0, 1}, {c, 0, 1},
TrackedSymbols \[Rule] {b, c}]
Run Code Online (Sandbox Code Playgroud)

相反(即,添加TrackedSymbols告诉Mathematica要跟踪更改的内容).


WRe*_*ach 6

是的,Manipulate将重新评估何时bc更改,但也会test更改 - 并且test每当这些值中的任何一个发生更改时重新分配.因此,无休止的重新评估循环.

作为一项规则,副作用应该在同样的结构的显示表达式来避免ManipulateDynamic为了避免评价循环,竞争条件和其他令人惊讶的行为.在手头的情况下,我建议删除隐含的依赖关系并b在以下方面test之外提升其定义Manipulate:

test[b_, c_] := 2*b; Manipulate[test[b, c], {b, 0, 1}, {c, 0, 1}]
Run Code Online (Sandbox Code Playgroud)

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