我想创建一个包含成员Point2D
和x
的复合类型y
,这很容易。但是我希望用非Point2D
s来参与正常的数学函数。例如,Point2D(1,2) + [1,1]
应该会产生值Vector{Int64}
的{{1}}。
我基于When is Julia's convert() used?创建了[2,3]
和convert
函数,但后来意识到我的类型需要是promote_rule
ed的某个子类型。但是,当我尝试从convert
或Vector
或任何类型的Vector{T}
或Array
进行子类型以尝试让我的类型参与转换时,我得到{{1 }}。如果作为实验,我将我的类型设为AbstractArray
的子类型,就像ERROR: invalid subtyping in definition of Point2D
一样,那么至少文件会加载而不会出错,但当然,当我尝试Number
时,我得到{{} 1}}。
我也尝试将type Point2D{T} <: Number
改为Point2D(1,2) + [1,1]
,但它也不会采取&#34;采取&#34; ERROR: no promotion exists for GridCalc.Point2D{Int64} and Int64
。
以下是代码:
Point2D
问题:
这是让mutable struct
参与数学函数的正确方法,就好像它是一个2向量一样吗?
如何让<: Vector{T}
成为type Point2D{T} # Fails when I add <: Vector{T}, etc.
x::T
y::T
end
# Convert a Point2D to a vector of the same type
convert{T1, T2<:Vector{T1}}(::Type{T2}, p::Point2D{T1}) = [p.x, p.y]
# Choose Vector when given the option
promote_rule{T1<:Real, T2<:Point2D{T1}, T3<:Vector{T1}}(::Type{T2}, ::Type{T3}) = T3
答案 0 :(得分:2)
执行此操作的方法是子类型AbstractVector{T}
。在Julia中,您只能对抽象类型进行子类型化; Vector{T}
是具体类型。您还必须实现一些必需的方法。有关详细信息,请参阅interfaces chapter:
julia> type Point2D{T} <: AbstractVector{T}
x::T
y::T
end
Base.getindex(p::Point2D, i::Int) = getfield(p, i)
Base.size(::Point2D) = (2,)
julia> Point2D(1,2)
2-element Point2D{Int64}:
1
2
julia> [1 2; 3 4; 5 6] * Point2D(1,2)
3-element Array{Int64,1}:
5
11
17
您还可以查看(和/或使用)JuliaGeometry organization和GeometryTypes.jl作为其点定义和周围方法。