在Julia中调用父函子

问题描述 投票:2回答:1

从1.3版开始,Julia允许functor dispatch on abstract types。因此,我想知道是否可以从子对象显式调用父函子。

例如在下面的示例中,是否可以通过(x::Foo)()对象调用bar::Bar

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
julia dispatch
1个回答
2
投票

如何使用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...)等)。

© www.soinside.com 2019 - 2024. All rights reserved.