nil*_*ock 37 wolfram-mathematica
Leonid在他的书第四章中写道:"......模块,块和With.这些结构在Mathematica Book和Mathematica Help中有详细解释,所以我在这里只会说几句......."
从我所读到的(能够找到)我仍然在黑暗中.对于打包的函数我(简单地)使用Module,因为它可以工作,我知道构造.但它可能不是最好的选择.我(从文档中)不清楚何时,何地或为何使用With(或Block).
And*_*lan 30
正如您所提到的,有许多事情需要考虑,并且可以进行详细讨论.但是我在大多数时间应用了一些经验法则:
Module[{x}, ...] 是最安全的,如果有的话可能需要
在评估模块期间,您希望避免破坏x的现有定义,或者
现有的代码依赖于未定义的 x (例如代码Integrate[..., x]).
模块也是创建和返回新符号的唯一选择.特别是,出于这个原因,有时在高级动态编程中需要模块.
如果您确信没有重要的现有x定义或任何依赖于它的代码未定义,那么Block[{x}, ...]通常会更快.(请注意,在您完全编码的项目中,对这些条件充满信心是一种合理的"封装"标准,您可能希望执行该标准,因此在这些情况下,Block通常是一个合理的选择.)
With[{x = ...}, expr]是唯一一个在内部注入x值的范围构造Hold[...].这很有用也很重要.With取决于expr和所采用的特定评估路径,可以比Block更快或更慢.With但是,由于无法在expr中更改x的定义,因此灵活性较低.
acl*_*acl 30
之间一个更实际的差异Block,并Module可以在这里看到:
Module[{x}, x]
Block[{x}, x]
(*
-> x$1979
x
*)
Run Code Online (Sandbox Code Playgroud)
所以,如果你想返回x,你可以使用Block.例如,
Plot[D[Sin[x], x], {x, 0, 10}]
Run Code Online (Sandbox Code Playgroud)
不起作用; 为了使它工作,人们可以使用
Plot[Block[{x}, D[Sin[x], x]], {x, 0, 10}]
Run Code Online (Sandbox Code Playgroud)
(当然这不是理想的,它只是一个例子).
另一个用途是类似的Block[{$RecursionLimit = 1000},...],它会暂时改变$RecursionLimit(Module在重命名时不会起作用$RecursionLimit).
人们也可以Block用来阻止某事的评估,例如
Block[{Sin}, Sin[.5]] // Trace
(*
-> {Block[{Sin},Sin[0.5]],Sin[0.5],0.479426}
*)
Run Code Online (Sandbox Code Playgroud)
即返回Sin[0.5]仅在Block执行完毕后才进行评估.这是因为Sin里面Block只是一个符号,而不是正弦函数.你甚至可以做类似的事情
Block[{Sin = Cos[#/4] &}, Sin[Pi]]
(*
-> 1/Sqrt[2]
*)
Run Code Online (Sandbox Code Playgroud)
(Trace用来看看它是如何工作的).因此,您也可以使用Block本地重新定义内置函数:
Block[{Plus = Times}, 3 + 2]
(*
-> 6
*)
Run Code Online (Sandbox Code Playgroud)
Men*_* Lu 11
我想提上的区别的官方文档Block和Module可在http://reference.wolfram.com/mathematica/tutorial/BlocksComparedWithModules.html.
Ver*_*eia 10
安德鲁已经提供了一个非常全面的答案.我只想总结一下,它Module是用于定义可以在函数定义范围内重新定义的局部变量,With而是用于定义局部常量,而不是.您也无法根据在同一With语句中设置的另一个局部常量的定义来定义局部常量,或者在定义的LHS上具有多个符号.也就是说,以下不起作用.
With[{{a,b}= OptionValue /@ {opt1,opt2} }, ...]
Run Code Online (Sandbox Code Playgroud)
我倾向于设置复杂的函数定义, Module并附上一个With.我设置了我可以在里面的所有局部常量With,例如Length传递给函数的数据,如果需要,那么根据需要设置其他局部变量.原因是,With你真的有一些常数而不是变量.