在 Julia 中调用父函子
Invoking parent functors in Julia
从 1.3 版开始,Julia 允许 functor dispatch on abstract types。因此,我想知道是否可以从子对象显式调用父仿函数。
例如在下面的示例中,是否有任何方法可以通过 bar::Bar
对象调用 (x::Foo)()
?
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
bar = Bar()
@info "Calling bar functor directly."
bar() |> println
@info "Invoking parent functor."
# ??? - how to invoke parent functor (x::Foo)() (e.g. desired output "Invoked Foo functor")
invoke(bar,Tuple{Bar}, bar) |> println
使用 default
结构怎么样?
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
struct DefaultFoo <: Foo end
#here we dont define an specialized method, DefaultFoo calls Foo
#an interface to define default methods:
default(x::Type{Foo}) = DefaultFoo
function parent(x::T) where {T}
y = default(supertype(T))
return y()
end
最后,你可以这样做来调用默认函数:
bar = Bar()
foo = parent(bar)
foo()
这需要为每个超类型定义一个 defaultFoo
类型和一个 default(x::Type{T})
。您可以使用以下宏自动执行此操作:
macro create_default_functor(type)
a = gensym(type)
esc(quote
struct $a <: $type end
default(x::Type{$type}) = $a
end)
end
使用宏和您的代码:
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
@create_default_functor Foo
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
function parent(x::T) where {T}
y = default(supertype(T))
return y()
end
#calling bar
bar = Bar()
bar()
#calling foo
foo = parent(bar)
foo()
我现在不具备直接在抽象类型定义上调用宏的宏知识,但这是一个开始。
关于抽象仿函数的是一个非常新的特性(1.3 还没有出来),如果你添加一个 PR 来建议这个特性,也许这可以添加到 julia 的未来版本中(类似于 call_parent(Foo,args...)
, )。
从 1.3 版开始,Julia 允许 functor dispatch on abstract types。因此,我想知道是否可以从子对象显式调用父仿函数。
例如在下面的示例中,是否有任何方法可以通过 bar::Bar
对象调用 (x::Foo)()
?
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
bar = Bar()
@info "Calling bar functor directly."
bar() |> println
@info "Invoking parent functor."
# ??? - how to invoke parent functor (x::Foo)() (e.g. desired output "Invoked Foo functor")
invoke(bar,Tuple{Bar}, bar) |> println
使用 default
结构怎么样?
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
struct DefaultFoo <: Foo end
#here we dont define an specialized method, DefaultFoo calls Foo
#an interface to define default methods:
default(x::Type{Foo}) = DefaultFoo
function parent(x::T) where {T}
y = default(supertype(T))
return y()
end
最后,你可以这样做来调用默认函数:
bar = Bar()
foo = parent(bar)
foo()
这需要为每个超类型定义一个 defaultFoo
类型和一个 default(x::Type{T})
。您可以使用以下宏自动执行此操作:
macro create_default_functor(type)
a = gensym(type)
esc(quote
struct $a <: $type end
default(x::Type{$type}) = $a
end)
end
使用宏和您的代码:
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
@create_default_functor Foo
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
function parent(x::T) where {T}
y = default(supertype(T))
return y()
end
#calling bar
bar = Bar()
bar()
#calling foo
foo = parent(bar)
foo()
我现在不具备直接在抽象类型定义上调用宏的宏知识,但这是一个开始。
关于抽象仿函数的是一个非常新的特性(1.3 还没有出来),如果你添加一个 PR 来建议这个特性,也许这可以添加到 julia 的未来版本中(类似于 call_parent(Foo,args...)
, )。