2016-10-15 40 views
3

在這個短序列中,用戶創建了一個函數userfunc(),但隨後想要更新第一個定義以執行不同的操作。然而programfunc()已經編譯了第一個版本,並繼續使用它。將更新函數傳遞給現有函數

userfunc(str, n) = str^n 
userfunc("hello", 3) 

"hellohellohello" 

# program makes use of the user's function 
programfunc(func, a, b) = func(a, b) 
programfunc(userfunc, "hello", 3) 

"hellohellohello" 

# now the user redefines the function 
userfunc(str, n) = str^(n * n) 
# userfunc("hello", 3) give "hellohellohellohellohellohellohellohellohello" 

# but program still makes use of the first userfunc() 
programfunc(userfunc, "hello", 3) 

"hellohellohello" 

因此,如何能programfunc()這樣定義:它總是使用傳遞給它的功能的最新定義是什麼?

+0

[相關的問題(https://github.com/JuliaLang/julia/issues/265#issuecomment-242102435) – Gnimuc

+0

@GnimucK 。啊,這是2011年的#265。固定爲0.6? – daycaster

回答

3

invoke會做到這一點。 (注意,雖然這可能不會編譯成漂亮的專用代碼)

這裏的問題是,專注於類型的茱莉亞。 也就是說,它爲每個傳遞給它的類型組合編譯一個自定義函數版本。 由於函數具有在朱0.5 (每個函數是一個單型。) ,導致它專門在功能

上0.5-RC0

julia> userfunc(str, n) = str^(n*n) 
WARNING: Method definition userfunc(Any, Any) in module Main at REPL[16]:1 overwritten at REPL[20]:1. 
userfunc (generic function with 1 method) 

julia> function programfunc(func, a, b) 
     invoke(func, (typeof(a), typeof(b)), a, b) 
     end 
programfunc (generic function with 1 method) 

julia> programfunc(userfunc, "hello", 3) 
"hellohellohellohellohellohellohellohellohello" 

julia> userfunc(str, n) = str^(n) 
WARNING: Method definition userfunc(Any, Any) in module Main at REPL[16]:1 overwritten at REPL[20]:1. 
userfunc (generic function with 1 method) 

julia> programfunc(userfunc, "hello", 3) 
"hellohellohello" 

注測試類型這也適用周圍#265

julia> foo(x)=2*x 
foo (generic function with 1 method) 


julia> function g(x) 
     invoke(foo, (typeof(x),), x) 
     end 
g (generic function with 1 method) 

julia> g(2) 
4 

julia> foo(x)=3*x 
WARNING: Method definition foo(Any) in module Main at REPL[1]:1 overwritten at REPL[10]:1. 
foo (generic function with 1 method) 

julia> g(2) 
6 
3

一個簡單的解決方法是使用一個匿名函數:

programfunc((x,y) -> userfunc(x,y), "hello", 3) 

這工作,因爲一個新的匿名函數每次創建:

julia> f(x) = x 
x -> f (generic function with 1 method) 

julia> x -> f(x) 
(::#15) (generic function with 1 method) 

julia> x -> f(x) 
(::#17) (generic function with 1 method) 
+0

謝謝!但是,如何聲明一個函數以便稍後接受未命名的函數? – daycaster

+0

我不明白這個問題。你可以傳遞一個匿名函數作爲參數傳遞給另一個函數,你可以在任何地方傳遞一個「普通」函數。那是你問的嗎? –

+0

換句話說,你不會改變原始函數中的任何內容,而是在你調用它的時刻。 –