抽象类型的子类型的通用构造函数

Chr*_*kas 6 types julia

我有一个类型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)和错误的包.朱莉娅是否以某种方式使用发动机罩下的调度?

Mat*_* B. 9

这看起来有点滑稽,但你实际上可以发送功能本身!对于构造函数,函数是有问题的类型:

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)

  • 构造函数只是名称恰好是类型的函数。它们通常返回该类型的实例,虽然这是一个非常强的约定,但并不是严格要求的。我希望 `AbstractT()` 返回 `AbstractT()` 的 _some_ 子类型,但在这个愚蠢的示例中,它实际上返回整数 `5`。 (2认同)