Function Set(=)和SetDelayed(:=)之间的区别是什么?

Function Set(=)和SetDelayed(:=)之间的区别是什么?,function,wolfram-mathematica,assignment-operator,Function,Wolfram Mathematica,Assignment Operator,这次讨论是在一次会议上进行的,我很想知道两者之间的区别。举例说明会很好。:=用于定义函数,=基本上用于设置值 ie:=将在读取时求值,设置时将求值 想想: x = 2 y = x z := x x = 4 现在,z是4,如果计算的话,y仍然是2 这是莱昂尼德·希夫林的书中的一个例子 这是解决这类问题的极好资源。见: 我们现在最重要的部分是r.h.s.,它包含x作为一个符号。对于评估来说,真正重要的是这种形式——规则在内部的存储方式。只要x在赋值时没有值,那么Set和SetDelayed都会在全

这次讨论是在一次会议上进行的,我很想知道两者之间的区别。举例说明会很好。

:=
用于定义函数,
=
基本上用于设置值

ie
:=
将在读取时求值,设置时将求值

想想:

x = 2
y = x
z := x
x = 4
现在,z是4,如果计算的话,y仍然是2 这是莱昂尼德·希夫林的书中的一个例子

这是解决这类问题的极好资源。见:

我们现在最重要的部分是r.h.s.,它包含
x
作为一个符号。对于评估来说,真正重要的是这种形式——规则在内部的存储方式。只要
x
在赋值时没有值,那么
Set
SetDelayed
都会在全局规则库中生成(创建)相同的规则,这就是最重要的。因此,它们在这方面是等价的

最终结果是一个符号
f
,它具有类似函数的行为,因为它的计算值取决于
x
的当前值。但是,这不是一个真正的函数,因为它没有任何参数,只触发符号
x
的更改。一般来说,不鼓励使用这种结构,因为在Mathematica中,对全局符号(变量)的隐式依赖与在其他语言中一样糟糕——它们使代码更难理解,错误更微妙,更容易忽略。可以找到一些相关的讨论


用于函数的集合
Set
可用于函数,有时需要。让我给你举个例子。这里,Mathematica象征性地求和,然后将其分配给aF(x),然后用于绘图

ClearAll[aF, x]

aF[x_] = Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}];

DiscretePlot[aF[x], {x, 1, 50}]

另一方面,如果尝试使用
SetDelayed
,则将要绘制的每个值传递给
Sum
函数。这不仅要慢得多,而且至少在Mathematica 7上,它完全失败了

ClearAll[aF, x]

aF[x_] := Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}];

DiscretePlot[aF[x], {x, 1, 50}]
如果希望确保形式参数的可能全局值(
x
此处)在定义新函数的过程中不受干扰且被忽略,则
Clear
的另一种替代方法是在定义周围环绕
Block

ClearAll[aF, x];
x = 1;
Block[{x}, aF[x_] = Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}]];
查看函数的定义可以确认我们得到了想要的:

?aF
Global`aF
aF[x_]=-(x/(-1+x+x^2))
从它们的属性可以看出,两个函数都保存第一个参数(您要为其赋值的符号),但它们的不同之处在于SetDelayed也保存第二个参数,而Set不保存第二个参数。这意味着Set将在赋值时计算
=
右侧的表达式。在实际使用变量之前,SetDelayed不会计算
:=
右侧的表达式

如果作业的右侧有副作用(例如打印[]),则发生的情况更清楚:


+1对于
x:=(打印[“SetDelayed”的右侧];3)
构造。这种类型的东西是一种方便的调试技术,可以查看何时触发规则。它在M8中也失败了。使用
Evaluate
帮助:
DiscretePlot[aF[x]//Evaluate,{x,1,50}]
对不起,我不理解您的斐波那契示例。当然,
SetDelayed
在这里是正确的选择:如果x>=1/GoldenRatio,则总和不会收敛。那么,为什么要在这里设置有利条件呢?@JoMo看起来这只是一个愚蠢的错误。奇怪的是,十多年来没有人指出这一点。非常感谢。 {10, 5, 2, 1, 3}
ClearAll[f, x]

f = 2 x;
f
2 x
x = 7;
f
14
x = 3;
f
6
In[84]:= OwnValues[f]

Out[84]= {HoldPattern[f] :> 2 x}
ClearAll[aF, x]

aF[x_] = Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}];

DiscretePlot[aF[x], {x, 1, 50}]
ClearAll[aF, x]

aF[x_] := Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}];

DiscretePlot[aF[x], {x, 1, 50}]
ClearAll[aF, x];
x = 1;
Block[{x}, aF[x_] = Sum[x^n Fibonacci[n], {n, 1, \[Infinity]}]];
?aF
Global`aF
aF[x_]=-(x/(-1+x+x^2))
In[1]:= Attributes[Set]

Out[1]= {HoldFirst, Protected, SequenceHold}

In[2]:= Attributes[SetDelayed]

Out[2]= {HoldAll, Protected, SequenceHold}
In[3]:= x = (Print["right hand side of Set"]; 3)
x
x
x

During evaluation of In[3]:= right hand side of Set

Out[3]= 3

Out[4]= 3

Out[5]= 3

Out[6]= 3

In[7]:= x := (Print["right hand side of SetDelayed"]; 3)
x
x
x

During evaluation of In[7]:= right hand side of SetDelayed

Out[8]= 3

During evaluation of In[7]:= right hand side of SetDelayed

Out[9]= 3

During evaluation of In[7]:= right hand side of SetDelayed

Out[10]= 3