更新:写这篇文章的时候没仔细研究过作用域,所以云里雾里。建议移步此处。
今天我遇到了一个比较坑爹的特性。先看下面这个macro的定义:
macro InitMat(A,value)
# tranlate Expressions to Instances
A1 = eval(A)
value1 = eval(value)
(m,n) = size(A1)
for i = 1:m
for j = 1:n
A1[i,j] = value1 # 改成 = eval(value)也一样
end
end
return A1
end
它的意思是把数组A的所有元素初始化为value。接下来我调用它把一个矩阵M初始化,令元素全部是Meson(4) (Meson(4)是我自定义的一个结构体),代码为:
M = @InitMat Array{Meson}(undef,4,5) Meson(4)
神奇的事情出现了。当我修改M的任意一个元素,所有元素全发生了相同变化。
但如果放弃用宏,而是直接赋值:
M = Array{Meson}(undef,4,5)
for i = 1:G.nx+1
for j = 1:2*G.ny+1
M[i,j] = Meson(4)
end
end
就不会产生以上问题。
结论是:Julia的宏似乎具有传址的特性,而且是一种发生在宏的整个作用域内的传址,跟通常的参数传址并不一样。虽然上述的宏定义中已经实施了一次eval(),但仍表现出了指针的行为。说实话没看懂,期待有人解答。
更新:
函数也是如此。
function InitMat(A::Matrix,v)
(m,n)=size(A)
for i = 1:m
for j=1:n
A[i,j] = v
end
end
return A
end