2017-03-18 57 views
3

當我重新定義一個已經傳遞給另一個函數的函數時,看起來重定義沒有被傳遞到該函數中。函數參數傳遞和函數重定義在Julia中

function foo(f) 
     f(3) 
    end 

f(x)=x 

foo(f) #=>3 

f(x)=x*x 

foo(f) #=>3 

f(3) #=>9 

這種行爲對我來說看起來很奇怪。這背後的邏輯是什麼?

+2

的[傳遞更新的功能,以現有的功能(可能的複製http://stackoverflow.com/questions/ 40057740 /傳遞更新函數到現有函數) – Gnimuc

+3

運行'f(x)= x * x'會提示'定義覆蓋'警告。警告提醒可能發生這種行爲。一般來說,當引用它的其他函數已經被編譯時,重新定義函數是非常棘手的。正如https://github.com/julialang/julia/issues/265從2011年表明,這是一個老問題,但我想程序可以重構,以避免這個問題。 –

+0

@DanGetz,你應該把它作爲答案。 – StefanKarpinski

回答

5

運行f(x)=x*x提示definition overwritten警告。警告提醒可能發生這種行爲。一般來說,當引用它的其他函數已經被編譯時,重新定義函數是非常棘手的。如2011年http://github.com/julialang/julia/issues/265所示,這是一個老問題。

程序可以小心避免這個問題。例如,在這個問題使用匿名函數與foo()會給:

julia> foo(x->x) 
3 
julia> foo(x->x*x) 
9 

在茱莉亞0.6這個問題解決了。 Github的問題詳細介紹了這個決議,但實質上,Julia跟蹤世界的版本號,並且一個函數「看到」某個世界版本。在REPL中,重定義會導致調用舊函數來觸發重新編譯(有關詳細信息,請參閱http://docs.julialang.org/en/latest/manual/methods.html#)。產生的行爲是不太怪異:

julia> # version 6.0 
julia> function foo(f) 
     f(3) 
     end 
foo (generic function with 1 method) 
julia> f(x)=x 
f (generic function with 1 method) 
julia> foo(f) 
3 
julia> f(x)=x*x 
f (generic function with 1 method)  
julia> foo(f) 
9 
julia> # :-) 

感謝@StefanKarpinski,@ChrisRackauckas