【问题标题】:julia global variable definition in let blocklet 块中的 julia 全局变量定义
【发布时间】:2018-01-12 13:42:09
【问题描述】:

我有以下 julia 函数

function fakeseq()
    let; global f(x)=unshift!(push!(x, 35) , 1);end; # not working
    #let; global f; f=x->unshift!(push!(x, 35) , 1);end; # works fine
    s1 = [rand(1:34) for i in 1:12]; 
    s2 = [rand(1:34) for i in 1:7]
    data = map(x->f(x), [s1, s2])
end

当我运行该代码时,我收到以下错误:

julia> fakeseq()
   ERROR: MethodError: no method matching f(::Array{Int64,1})
   The applicable method may be too new: running in world age 21823, while current world is 21824.
   Closest candidates are:        f(::Any) at REPL[1]:2 (method too new to be called from this world context.)
   Stacktrace:
   [1] _collect(::Array{Array{Int64,1},1}, 
   ::Base.Generator{Array{Array{Int64,1},1},##3#6}, ::Base.EltypeUnknown, 
   ::Base.HasShape) at ./array.jl:488
   [2] fakeseq() at ./REPL[1]:6

但是,# works fine 注释指示的 f 的第二个定义有效。我无法得到它们之间的确切区别,为什么会这样?

【问题讨论】:

  • 查看Redefining Methods 上的 julia 文档。另外,我希望您会得到不同的结果,具体取决于 a) 您运行上述定义的顺序(确保您从新的 julia 会话开始。)
  • 您也在使用 julia v0.6 吗?我没想到它会让你重新定义f句号...
  • @Alexander Morley 我正在使用 julia v0.6.2。问这个问题时,我的意思是我在新的 julia 会话中只使用了上述 let 块之一。

标签: julia let


【解决方案1】:

正如@AlexanderMorley 指出的那样,您需要仔细查看

https://docs.julialang.org/en/latest/manual/methods.html#Redefining-Methods-1

或观看 Jameson 的 Youtube 视频:

https://www.youtube.com/watch?v=7KGZ_9D_DbI

在 Julia 中,泛型函数的处理方式与匿名函数有些不同。在泛型函数情况下,发生的事情是这样的,程序编译知道全局函数表中的f 是什么,你修改f,但调用函数已经编译为调用不再正确的函数因此它会出错。错误是停止Issue #265。匿名函数是不同的。在匿名函数的情况下,调用函数被设置为调用该变量指向的任何函数。在这种情况下,它也知道它是一个全局变量,所以它是安全的,不会内联它或类似的东西,所以它是成功的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2015-04-29
    • 2020-06-09
    • 2013-01-16
    相关资源
    最近更新 更多