Generics 参数化别名的构造函数

Generics 参数化别名的构造函数,generics,julia,Generics,Julia,我使用附加的泛型参数指定了一个自定义的AbstractArray类型。 我想为矩阵创建一个别名并使用现有的外部构造函数, 但偶然发现了这样一种行为: struct MyArray{T,N,K} <: AbstractArray{T,N} t::T end MyMatrix{T} = MyArray{T,2,1} MyArray{T,N,K}(x::AbstractArray{T,N}) where {T,N,K} = MyArray{T,N,K}(x[1]) mat = My

我使用附加的泛型参数指定了一个自定义的
AbstractArray
类型。 我想为矩阵创建一个别名并使用现有的外部构造函数, 但偶然发现了这样一种行为:

struct MyArray{T,N,K} <: AbstractArray{T,N}
    t::T
end

MyMatrix{T} = MyArray{T,2,1}

MyArray{T,N,K}(x::AbstractArray{T,N}) where {T,N,K} = MyArray{T,N,K}(x[1])

mat = MyMatrix([1 2; 3 4])
对我来说,类型为
MyArray{T,2,1}的构造函数调用,其中T(::Array{Int64,2})
应该能够使用 已经申报的那个。 我有几个其他的外部构造函数,但都是用于泛型
MyArray
(显然,上述任何一项法规都不会成为法律)

如果我声明了一个特定的构造函数,那么一切都可以正常工作:

MyMatrix(x::AbstractMatrix{T}) where {T} = MyMatrix{T}(x[1])
但是,为别名设置构造函数似乎是多余的

类似地,我可以通过构造函数调用指定类型:

mat = MyMatrix{Int}([1 2; 3 4])
但是这里的信息也被重复,因为类型可以从参数中推断出来


当我使用矩阵类型时,有没有办法不重复类型或专门化构造函数?

附带的信息是
MyMatrix(x)
不知道如何推断参数
t
。但您始终可以明确定义所需的行为


我需要一段时间才能理解你的问题,如果我错了,请纠正我。 假设我们只定义了
MyArray
和别名
MyMatrix

struct MyArray{T,N,K} <: AbstractArray{T,N}
    t::T
end

MyMatrix{T} = MyArray{T,2,1}
我猜您可以假定类型参数
T
可以推断为
Int64
。不幸的是没有。但您可以这样定义一个构造函数:

MyMatrix(x::T) where T = MyMatrix{T}(x)
现在第二个问题是我们有了一个默认的
MyArray
构造函数:

MyArray{T,N,K}(x::AbstractArray{T,N}) where {T,N,K} = MyArray{T,N,K}(x[1])
您希望
MyMatrix([12;34])==MyMatrix{Int}(1)
。但实际上,它只会调用我们刚才定义的方法:

julia> @which MyMatrix([1 2; 3 4])
(::Type{MyArray{T,2,1} where T})(x::T) where T in Main at REPL[3]:1
因此,我们可以定义另一个更具体的方法(但不像您提供的那样具体;)

然后它将回到您对MyArray{T,N,K}(x::AbstractArray{T,N})的一般定义,其中{T,N,K}=MyArray{T,N,K}(x[1])

MyArray{T,N,K}(x::AbstractArray{T,N}) where {T,N,K} = MyArray{T,N,K}(x[1])
julia> @which MyMatrix([1 2; 3 4])
(::Type{MyArray{T,2,1} where T})(x::T) where T in Main at REPL[3]:1
MyMatrix(x::AbstractArray{T}) where T = MyMatrix{T}(x)
julia> @code_typed MyMatrix([1 2; 3 4])
CodeInfo(
1 ─ %1 = (Base.arrayref)(true, x, 1)::Int64
│   %2 = %new(MyArray{Int64,2,1}, %1)::MyArray{Int64,2,1}
└──      return %2
) => MyArray{Int64,2,1}