Julia-Lang匿名vs传递参数

时间:2015-10-04 07:18:11

标签: pointers julia

请参阅Julia doc:

  

在Julia中,函数的所有参数都通过引用传递。

当我从匿名函数中获取Float64参数的内存地址时,它看起来是正确的。但对于命名函数而言并非如此。

test = function (a::Float64)
    println(pointer_from_objref(a));
end
# => (anonymous function)
function test1(a::Float64)
    println(pointer_from_objref(a));
end
# => test1 (generic function with 1 method)
value=0.0;
println(pointer_from_objref(value))
# => Ptr{Void} @0x00007fe797c5c020
test(value)
# => Ptr{Void} @0x00007fe797c5c020
test1(value)
# => Ptr{Void} @0x00007fe799e83960

正如@Gnimuc所说,Julia-Lang Doc还有另一段解释论证传递行为

  

Julia函数参数遵循有时称为的约定   “pass-by-sharing”,这意味着值不会被复制   被传递给函数。函数参数本身就是新的   变量绑定(可以引用值的新位置),但是   他们引用的值与传递的值相同。

这种“传递共享”行为与上述代码之间是否有任何关系?

2 个答案:

答案 0 :(得分:0)

pointer_from_objref(object_instance)函数的Julia文档中我们得到了这样的描述:

  

将Julia对象的内存地址作为Ptr获取。存在   生成的Ptr不会保护对象免受垃圾收集,   所以你必须确保整个对象仍然被引用   将使用Ptr的时间。

检查以下测试:

x=10
y=10
println(pointer_from_objref(x)) # => Ptr{Void} @0x039ee2c0
println(pointer_from_objref(y)) # => Ptr{Void} @0x039ee2c0

正如我们所看到的,pointer_from_objref无法返回不可变对象的本地地址,这是因为这些对象是按值传递的,所以我认为上面问题的答案是pointer_from_objref在那里被误用了。

答案 1 :(得分:0)

扩展Reza的答案,这里要注意的是“传递共享”推理不适用于不可变对象。如果您尝试相同的代码,但使用浮点数向量作为参数,您会得到预期的行为,即所有指针都是相同的:

    test = function (a::Vector{Float64})
        println(pointer_from_objref(a));
    end

    # => (anonymous function)
    function test1(a::Vector{Float64})
        println(pointer_from_objref(a));
    end

    # => test1 (generic function with 1 method)
    value=[0.0,0.1];

    println(pointer_from_objref(value))
    # => Ptr{Void} @0x0000000084601be0
    test(value)
    # => Ptr{Void} @0x0000000084601be0
    test1(value)
    # => Ptr{Void} @0x0000000084601be0