Трудно об этом говорить абстрактно. Вот конкретный пример:
struct ReversedRowMajor{T,A} <: AbstractMatrix{T}
data::A
end
ReversedRowMajor(data::AbstractMatrix{T}) where {T} = ReversedRowMajor{T, typeof(data)}(data)
Base.size(R::ReversedRowMajor) = reverse(size(R.data))
Base.getindex(R::ReversedRowMajor, i::Int, j::Int) = R.data[end-j+1, end-i+1]
Этот простой массив обращается к родительскому массиву с его переставленными индексами (чтобы быть основным рядом) и преобразованным (чтобы быть обращенным). Обратите внимание, что этот массив автоматически поддерживает все ожидаемые формы индексации:
julia> R = ReversedRowMajor([1 2; 3 4; 5 6])
2×3 ReversedRowMajor{Int64,Array{Int64,2}}:
6 4 2
5 3 1
julia> R[:, isodd.(R[1,:].÷2)]
2×2 Array{Int64,2}:
6 2
5 1
julia> @view R[[1,4,5]]
3-element view(reshape(::ReversedRowMajor{Int64,Array{Int64,2}}, 6), [1, 4, 5]) with eltype Int64:
6
3
2
Обратите внимание, что мы не переиндексируем в R
переставленные и вычисленные индексы - новые индексы передаются непосредственно в родительский массив R.data
.
Теперь, to_indices
, с другой стороны, выполняет простые преобразования ранее неподдерживаемого индекса типов в Int
или массивов Int
, а затем переиндексирует в R
сам с эти преобразованные индексы. Обратите внимание, что происходит, когда вы звоните R[Int8(1),Int8(1)]
:
julia> @which R[Int8(1),Int8(1)]
getindex(A::AbstractArray, I...) in Base at abstractarray.jl:925
Это не вызывает метод, который вы определили - пока нет. Вы не определили, как getindex(::ReversedRowMajor, ::Int8, ::Int8)
. Итак, Джулия занимается этим делом для вас. Он использует to_indices
для преобразования Int8
в Int
, а затем снова вызывает R[1,1]
. Теперь он попадает в метод, который вы определили.
Вкратце: Этот массив имеет простой метод getindex
с индексами Int
, который пересчитывает доступы в родительский массив . to_indices
, с другой стороны, преобразует все другие типы индексов в поддерживаемые индексы в тот же массив в тех случаях, когда вы не определили метод сопоставления. Вы просто не можете выполнить нужное преобразование с помощью to_indices
, потому что неясно, использует ли R[1, 2]
пре-преобразованные индексы или пост-преобразованные индексы.