在这个简短的序列中,用户创建一个函数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 :(得分:3)
invoke
会这样做。 (注意,虽然这可能无法编译成很好的专用代码)
这里的问题是julia专注于Type。 也就是说,它为传递给它的每种类型组合编译函数的自定义版本。 由于函数在julia中的类型为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
答案 1 :(得分: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)