Julia 朱莉娅:在函数中更新浮点64

Julia 朱莉娅:在函数中更新浮点64,julia,Julia,我试图创建一个函数来更新Float64参数。下面的例子应该能够阐明我试图实现的目标 a=1.2 function fun!(a) a=3.4; end 不幸的是,a仅在本地范围内更新。有办法吗?我认为传递一个指向函数的指针可能会有所帮助,但我不确定如何在Julia中实现这一点。你不能这样做。AFloat64不是可变值,因此不能对A的值进行变异。只能用单独的Float64替换a。这就是不可变值的含义 更低级的(通常是这样,尽管有例外):Float64s由它们的实际字节表示,而可变项是指向

我试图创建一个函数来更新Float64参数。下面的例子应该能够阐明我试图实现的目标

a=1.2

function fun!(a)
   a=3.4;
end

不幸的是,
a
仅在本地范围内更新。有办法吗?我认为传递一个指向函数的指针可能会有所帮助,但我不确定如何在Julia中实现这一点。

你不能这样做。A
Float64
不是可变值,因此不能对A的值进行变异。只能用单独的
Float64
替换
a
。这就是不可变值的含义


更低级的(通常是这样,尽管有例外):
Float64
s由它们的实际字节表示,而可变项是指向实际字节的指针。可变表的实际值是其指针。变异意味着更改指针指向的内存位置的值,但不可变的内存位置不存在此值。

要完成答案,如果您有C/C++背景:

  • 可变对象通常在堆上分配,并具有稳定的内存地址。它们是通过引用传递的
  • 不可变对象位于堆栈上,并通过副本传递
还有,好的,
的<代码>乐趣
只是一个名称约定来吸引注意,它与julia内部结构无关。你可以随心所欲地写
fun

示例:

v=ones(3);                         # [1 1 1]
isimmutable(v)                     # false -> v is passed by reference
foo(v::Array{Float64}) = v .*= 2;  # hence v can be modified
foo(v); 
v                                  # [2 2 2]

v=Int(1)                           # 1
isimmutable(v)                     # true -> v is passed by copy
foo(v::Int) = v *= 2               # use a local copy of v
foo(v)                             # returns 2, but it is a local copy
v                                  # 1 (unmodified because we worked with a copy)
也看到

Ref{}示例:

v=ones(3);                         # [1 1 1]
isimmutable(v)                     # false -> v is passed by reference
foo(v::Array{Float64}) = v .*= 2;  # hence v can be modified
foo(v); 
v                                  # [2 2 2]

v=Int(1)                           # 1
isimmutable(v)                     # true -> v is passed by copy
foo(v::Int) = v *= 2               # use a local copy of v
foo(v)                             # returns 2, but it is a local copy
v                                  # 1 (unmodified because we worked with a copy)
以赛亚·诺顿评论

foo(r::Ref{Int}) = r[] *= 2

r=Ref{Int}(1)     # Base.RefValue{Int64}(1)
foo(r);
r                 # Base.RefValue{Int64}(2)
FWIW您可以执行
a=Ref(1.2)
,然后
a[]=3.4
在函数内部进行修改。这将创建一个可垃圾回收的可变内存块(如1元素数组)。使用REF有一些很好的理由,但它们通常不应该是第一选择,所以确保你需要这样的突变——背景见Chris的答案。