# Defining custom subtype of AbstractArray

**URL:** <https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799>\
**Category:** General Usage\
**Created:** [December 18, 2018, 2:17pm UTC](https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799 "2018-12-18T14:17:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ArjunNarayanan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arjunnarayanan/32/6475_2.png) [@ArjunNarayanan](https://discourse.julialang.org/u/ArjunNarayanan)\
**Post date:** [December 18, 2018, 2:17pm UTC](https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799/1 "2018-12-18T14:17:58Z")

</div>

I am having some trouble defining my `struct` as a subtype of `AbstractArray`.

As an example, say I want to define a `Point` in `dim` dimensional space as follows:

```julia
struct Point{dim} <: AbstractArray{Float64,dim}
	x::NTuple{dim, Float64}
end

```

Now according to the documentation, the minimum functions I need to overload for `Point` to be an `AbstractArray` are: `Base.size, Base.IndexStyle, Base.getindex` and `Base.setindex!`

So I do it as follows:

```julia
Base.size(p::Point{dim}) where dim = (dim,)
Base.IndexStyle(::Type{<:Point}) = IndexLinear()
Base.getindex(p::Point{dim}, i::Int64) where dim = p.x[i]
Base.setindex!(p::Point{dim}, v, i::Int64) where dim = (p.x[i] = v)

```

If I try to initialize this `struct`, I get an error message that I can’t quite understand:

```julia
julia> Point((1.5,2.4))
2-element Point{2}:Error showing value of type Point{2}:
ERROR: BoundsError: attempt to access (Base.OneTo(2),)
  at index [2]
Stacktrace:
 [1] getindex(::Tuple{Base.OneTo{Int64}}, ::Int64) at ./tuple.jl:24
 [2] axes at ./abstractarray.jl:57 [inlined]
...

```

I would greatly appreciate inputs on the correct way to do this.

Thanks!

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 18, 2018, 2:21pm UTC](https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799/2 "2018-12-18T14:21:47Z")

</div>

Your trouble is stemming from the fact that you’re reporting to `AbstractArray` that your struct has `dim` dimensions when it’s only 1-dimensional. Change it to `struct Point{dim} <: AbstractArray{Float64,1}` and I think all should work. I’d probably rename `dim` to `len` to make it clearer.

Oh, not quite all will work: Your `setindex!` method will run into trouble since tuples are immutable, so if you use a tuple as your backing you need to make the strict itself mutable and replace the entire tuple when you change it.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [December 18, 2018, 2:46pm UTC](https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799/3 "2018-12-18T14:46:45Z")

</div>

Also for generality you could do:

```julia
struct Point{T,dim} <: AbstractArray{T,1}
    x::NTuple{dim, T}
end

```

So its not limited to `Float64`

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 18, 2018, 2:54pm UTC](https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799/4 "2018-12-18T14:54:35Z")

</div>

You’ve actually re-created the bug in the original post. You want `<: AbstractArray{T, 1}`, not `<: AbstractArray{T, dim}`.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [December 18, 2018, 3:12pm UTC](https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799/5 "2018-12-18T15:12:48Z")

</div>

Oops I thought that looked weird! mbaumans code change _is_ kinda hard to read in inline quotes 😉

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [December 18, 2018, 3:31pm UTC](https://discourse.julialang.org/t/defining-custom-subtype-of-abstractarray/18799/6 "2018-12-18T15:31:09Z")

</div>

If you make it `mutable Point{dim, T} <: AbstractVector{T}` (here `AbstractVector{T}` is shorthand for `AbstractArray{T, 1}`), then consider

```julia
@inline Base.setindex!(p::Point{dim, T}, v, i::Int64) where {dim, T}
    @boundscheck checkbounds(p, i)
    if isbitstype(T)
        GC.@preserve p Base.unsafe_store!(convert(Ptr{T}, pointer_from_objref(p)), convert(T, v), i)
        return v
    else
        vv = convert(T, v)
        p.x = ntuple( (n-> (n===i ? vv : @inbounds p.x[n]) ), dim)
        return v
    end
end

```

This is what `StaticArrays` does for `MVector`.
