Julia 基本结构的显示和广播错误

Julia 基本结构的显示和广播错误,julia,Julia,我在定义复合类型时有两个问题 我将遵循Julia v0.6中手册的接口部分。我构建了一个简单的最小(非)工作示例: mutable struct Group <: AbstractArray{Integer, 1} x1::Int64 x2::Int64 end Base.size(g::Group) = 2 Base.length(g::Group) = 2 Base.eltype(::Type{Group}) = Int64 Base.getindex(g::Grou

我在定义复合类型时有两个问题

我将遵循Julia v0.6中手册的接口部分。我构建了一个简单的最小(非)工作示例:

mutable struct Group <: AbstractArray{Integer, 1}
    x1::Int64
    x2::Int64
end

Base.size(g::Group) = 2
Base.length(g::Group) = 2
Base.eltype(::Type{Group}) = Int64
Base.getindex(g::Group, i::Int64) = getindex([g.x1, g.x2], i)
Base.setindex!(g::Group, v, i::Int64) = Base.setindex!(g, v, i)
Base.IndexStyle(::Type{<:Group}) = IndexLinear()

Base.start(g::Group) = 1
Base.next(g::Group, s::Int) = g[s], s+1
Base.done(g::Group, s::Int) = (s > length(g))

Base.show(io::IO, g::Group) = print("\t", string(g.x1), "\n\t", string(g.x2))
但是:

这给出了错误(在Juno中):

但是:

第二个问题是因为我想使用广播:

julia> sin.(g)
然后我得到这个错误:

MethodError: Cannot `convert` an object of type Base.OneTo{Int64} to an
object of type CartesianRange
This may have arisen from a call to the constructor CartesianRange(...),
since type constructors fall back to convert methods.
CartesianRange(::Base.OneTo{Int64}) at sysimg.jl:77
broadcast_c at broadcast.jl:314 [inlined]
broadcast(::Function, ::Group) at broadcast.jl:455
include_string(::String, ::String) at loading.jl:522
include_string(::String, ::String, ::Int64) at eval.jl:30
include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N}
where N) at eval.jl:34
(::Atom.##102#107{String,Int64,String})() at eval.jl:82
withpath(::Atom.##102#107{String,Int64,String}, ::Void) at utils.jl:30
withpath(::Function, ::String) at eval.jl:38
hideprompt(::Atom.##101#106{String,Int64,String}) at repl.jl:67
macro expansion at eval.jl:80 [inlined]
(::Atom.##100#105{Dict{String,Any}})() at task.jl:80

这不是很有帮助。我显然需要在
组的定义中添加一些其他内容

问题是
size
方法返回一个整数
size
应该返回一个整数元组,每个维度的长度都是整数。在这种情况下,当我们定义一个向量时,它应该返回一个1元组,类似于:

Base.size(::Group) = (2, )
不幸的是,这会导致下游出现一些模糊的错误消息


其他一些可能有用的评论:

您的getindex工作正常,但分配了一个不必要的
向量,也许下面的方法会更好:

function Base.getindex(g::Group, i::Int)
    if i == 1
        return g.x1
    elseif i == 2
        return g.x2
    else
        throw(BoundsError(g, i))
    end
end
function Base.setindex!(g::Group, v, i)
    println("setindex!(:Group, v = $v, i = $i)")
    if i == 1
        g.x1 = v
    elseif i == 2
        g.x2 = v
    else
        throw(BoundsError(g, i))
    end
end
您对
setindex的定义
调用自身并将导致
堆栈溢出
错误,也许下面这样更好:

function Base.getindex(g::Group, i::Int)
    if i == 1
        return g.x1
    elseif i == 2
        return g.x2
    else
        throw(BoundsError(g, i))
    end
end
function Base.setindex!(g::Group, v, i)
    println("setindex!(:Group, v = $v, i = $i)")
    if i == 1
        g.x1 = v
    elseif i == 2
        g.x2 = v
    else
        throw(BoundsError(g, i))
    end
end

问题是
size
方法返回一个整数
size
应该返回一个整数元组,每个维度的长度都是整数。在这种情况下,当我们定义一个向量时,它应该返回一个1元组,类似于:

Base.size(::Group) = (2, )
不幸的是,这会导致下游出现一些模糊的错误消息


其他一些可能有用的评论:

您的getindex工作正常,但分配了一个不必要的
向量,也许下面的方法会更好:

function Base.getindex(g::Group, i::Int)
    if i == 1
        return g.x1
    elseif i == 2
        return g.x2
    else
        throw(BoundsError(g, i))
    end
end
function Base.setindex!(g::Group, v, i)
    println("setindex!(:Group, v = $v, i = $i)")
    if i == 1
        g.x1 = v
    elseif i == 2
        g.x2 = v
    else
        throw(BoundsError(g, i))
    end
end
您对
setindex的定义
调用自身并将导致
堆栈溢出
错误,也许下面这样更好:

function Base.getindex(g::Group, i::Int)
    if i == 1
        return g.x1
    elseif i == 2
        return g.x2
    else
        throw(BoundsError(g, i))
    end
end
function Base.setindex!(g::Group, v, i)
    println("setindex!(:Group, v = $v, i = $i)")
    if i == 1
        g.x1 = v
    elseif i == 2
        g.x2 = v
    else
        throw(BoundsError(g, i))
    end
end