Set ( = ) 和 SetDelayed ( := ) 有什么区别?
此讨论出现在上一个问题中,我有兴趣了解之间的区别两个。举例说明会很好。
This discussion came up in a previous question and I'm interested in knowing the difference between the two. Illustration with an example would be nice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
基本示例
是 Leonid Shifrin 的书 Mathematica 编程:高级介绍 中的示例
这 是解决此类问题的绝佳资源。请参阅:(1) (2)
复杂示例
上面的示例可能会给人这样的印象:一旦使用
Set
,其值是固定的,不会改变。事实并非如此。f = ...
向f
分配一个表达式,在赋值时计算它的值。如果符号保留在该计算表达式中,并且稍后它们的值发生变化,那么f
的表观值也会发生变化。记住规则如何在内部存储是很有用的。对于分配了值作为
symbol = expression
的符号,规则存储在OwnValues
中。通常(但并非总是),OwnValues
仅包含一条规则。在这种特殊情况下,现在对我们来说重要的部分是 rhs,它包含
x
作为符号。对于评估来说真正重要的是这种形式——规则在内部存储的方式。只要x
在赋值时没有值,Set
和SetDelayed
都会产生(创建)与上面相同的规则全局规则库,这才是最重要的。因此,它们在这种情况下是等效的。最终结果是一个具有类似函数行为的符号
f
,因为它的计算值取决于x
的当前值。然而,这不是一个真正的函数,因为它没有任何参数,并且仅触发符号x
的更改。一般来说,应该不鼓励使用此类构造,因为对全局符号(变量)的隐式依赖在 Mathematica 中与在其他语言中一样糟糕 - 它们使代码更难理解,并且错误更微妙且更容易被忽视。可以在此处找到一些相关的讨论。用于函数的集合
Set
可以用于函数,有时也需要如此。让我举个例子。这里,Mathematica 象征性地求解 Sum,然后将其分配给 aF(x),然后将其用于绘图。另一方面,如果您尝试使用
SetDelayed
那么您将传递每个值绘制到Sum
函数中。这不仅会慢得多,而且至少在 Mathematica 7 上,它完全失败。如果想要确保形式参数的可能全局值(此处为
x
)不会干扰并在定义新函数的过程中被忽略,可以使用Clear
的替代方法是将Block
包裹在定义中:查看函数的定义可以确认我们得到了我们想要的结果:
Basic Example
Here is an example from Leonid Shifrin's book Mathematica programming: an advanced introduction
It is an excellent resource for this kind of question. See: (1) (2)
Complicated Example
The example above may give the impression that once a definition for a symbol is created using
Set
, its value is fixed, and does not change. This is not so.f = ...
assigns tof
an expression as it evaluates at the time of assignment. If symbols remain in that evaluated expression, and later their values change, so does the apparent value off
.It is useful to keep in mind how the rules are stored internally. For symbols assigned a value as
symbol = expression
, the rules are stored inOwnValues
. Usually (but not always),OwnValues
contains just one rule. In this particular case,The important part for us now is the r.h.s., which contains
x
as a symbol. What really matters for evaluation is this form - the way the rules are stored internally. As long asx
did not have a value at the moment of assignment, bothSet
andSetDelayed
produce (create) the same rule above in the global rule base, and that is all that matters. They are, therefore, equivalent in this context.The end result is a symbol
f
that has a function-like behavior, since its computed value depends on the current value ofx
. This is not a true function however, since it does not have any parameters, and triggers only changes of the symbolx
. Generally, the use of such constructs should be discouraged, since implicit dependencies on global symbols (variables) are just as bad in Mathematica as they are in other languages - they make the code harder to understand and bugs subtler and easier to overlook. Somewhat related discussion can be found here.Set used for functions
Set
can be used for functions, and sometimes it needs to be. Let me give you an example. Here Mathematica symbolically solves the Sum, and then assigns that to aF(x), which is then used for the plot.If on the other hand you try to use
SetDelayed
then you pass each value to be plotted to theSum
function. Not only will this be much slower, but at least on Mathematica 7, it fails entirely.If one wants to make sure that possible global values for formal parameters (
x
here) do not interfere and are ignored during the process of defining a new function, an alternative toClear
is to wrapBlock
around the definition:A look at the function's definition confirms that we get what we wanted:
从它们的属性可以看出,这两个函数都保存其第一个参数(您要分配的符号),但它们的不同之处在于 SetDelayed 还保存其第二个参数,而 Set 则不保存。这意味着 Set 将在进行赋值时计算
=
右侧的表达式。在实际使用该变量之前,SetDelayed 不会计算:=
右侧的表达式。如果赋值的右侧有副作用(例如 Print[]),则发生的情况会更清楚:
As you can see by their attributes, both functions hold their first argument (the symbol to which you are assigning), but they differ in that SetDelayed also holds its second argument, while Set does not. This means that Set will evaluate the expression to the right of
=
at the time the assignment is made. SetDelayed does not evaluate the expression to the right of the:=
until the variable is actually used.What's happening is more clear if the right hand side of the assignment has a side effect (e.g. Print[]):
基本上,
:=
用于定义函数,=
用于设置值。即
:=
将在读取时评估,=
将在设置时评估。想一想:
现在,如果在 y 仍为 2 时求值,则 z 为 4
:=
is for defining functions and=
is for setting a value, basically.ie
:=
will evaluate when its read,=
will be evaluated when it is set.think about:
Now, z is 4 if evaluated while y is still 2