我有一个类型AbstractT,我想要定义一个构造函数的每个子类型T(x::Tuple),但我找不到一个通用的方法来做它,因为像这样的Julia中的所有东西都使用dispatch,但我不能在构造函数上调度,因为构造函数的名称匹配类型,所以每个构造函数是一个不同的函数.即如果有的话,它会起作用
construct{T<:AbstractT}(::Type{T},x::Tuple) = # Define all the constructors
Run Code Online (Sandbox Code Playgroud)
我在内部这样做,但它不能很好地与其他将直接调用T(x)和错误的包.朱莉娅是否以某种方式使用发动机罩下的调度?
这看起来有点滑稽,但你实际上可以发送功能本身!对于构造函数,函数是有问题的类型:
julia> abstract type AbstractT end
julia> struct ConcreteT{T} <: AbstractT; end
julia> (::Type{ConcreteT{Int}})() = 1
julia> (::Type{ConcreteT{Float64}})() = 2
julia> ConcreteT{Int}()
1
julia> ConcreteT{Float64}()
2
Run Code Online (Sandbox Code Playgroud)
你甚至可以使用类型参数...它们位于函数名和参数列表之间的正常位置,所以它看起来有点倒退,但它工作得很好:
julia> (::Type{ConcreteT{T}})() where {T<:Number} = 3
julia> (::Type{ConcreteT{T}})() where {T<:AbstractArray} = 4
julia> ConcreteT{Float32}()
3
julia> ConcreteT{UnitRange{Int}}()
4
Run Code Online (Sandbox Code Playgroud)
您甚至可以使用抽象类型执行此操作,但请注意:
julia> (::Type{T})() where {T<:AbstractT} = 5
julia> ConcreteT{String}()
ConcreteT{String}()
julia> AbstractT()
5
Run Code Online (Sandbox Code Playgroud)
为什么抽象构造函数不起作用ConcreteT{String}?回想一下,Julia为你创建构造函数......因为这只是调度,所以这些构造函数更具体并且优先:
julia> methods(ConcreteT{String})
# 2 methods for type constructor:
[1] (::Type{ConcreteT{T}})() where T in Main at REPL[2]:1
[2] (::Type{T})() where T<:AbstractT in Main at REPL[12]:1
Run Code Online (Sandbox Code Playgroud)
因此在使用此功能时需要小心; 只有当它不与你的叶子构造器冲突时它才会起作用:
julia> (::Type{T})(x) where {T<:AbstractT} = x
julia> ConcreteT{String}(6)
6
julia> ConcreteT{Int}(7)
7
Run Code Online (Sandbox Code Playgroud)