Indexing Julia在访问数组时重新定义索引

Indexing Julia在访问数组时重新定义索引,indexing,julia,Indexing,Julia,我有一个实现数组接口的结构。我想在访问它时重新定义索引。到目前为止,我是在我的类型的Base.getindex函数中完成的,但是我在文档中看到了Base.to\u index函数,不知道它们是如何协同工作的 可以使用:(Colon)、UnitRange、StepRange、OneTo、Int或Int数组访问数组元素,那么我应该在哪里重新定义索引而不必管理所有这些情况呢?在摘要中很难谈论这一点。下面是一个具体的例子: struct ReversedRowMajor{T,A} <: Abstr

我有一个实现数组接口的结构。我想在访问它时重新定义索引。到目前为止,我是在我的类型的
Base.getindex
函数中完成的,但是我在文档中看到了
Base.to\u index
函数,不知道它们是如何协同工作的


可以使用
Colon
)、
UnitRange
StepRange
OneTo
Int
Int数组
访问数组元素,那么我应该在哪里重新定义索引而不必管理所有这些情况呢?

在摘要中很难谈论这一点。下面是一个具体的例子:

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]
请注意,我们没有使用排列和计算的索引重新索引到
R
——新的索引直接提供给父数组
R.data

另一方面,
to_index
,将以前不受支持的索引类型简单转换为
Int
Int
数组,然后使用这些转换后的索引将索引重新转换为
R
本身。注意调用
R[Int8(1),Int8(1)]
时会发生什么:

这并没有调用您定义的任何方法-还没有。您没有定义如何
获取索引(::ReversedRowMajor,::Int8,::Int8)
。朱莉娅正在为你处理这个案子。它使用
to_index
Int8
转换为
Int
,然后再次调用
R[1,1]
。现在它击中了您定义的方法


简言之:此数组有一个简单的
getindex
方法,该方法使用
Int
索引重新计算对父数组的访问<另一方面,如果您没有定义匹配方法,则code>to_index会将所有其他类型的索引转换为支持的索引,并将其转换为相同的数组。您无法使用
到_index
进行所需的转换,因为不清楚
R[1,2]
是使用转换前的索引还是转换后的索引。

您所说的“重定义”是什么意思?你能举一个你想发生什么的例子吗?例如,排列索引并对它们应用转换(
i=f(i)
)你是对的,在这个例子中谈论它更容易。在这个例子中(离我想做的不远),如果调用R[:,:],就会出现性能问题,因为eachindex将以笛卡尔指数的非最佳顺序迭代。有没有办法告诉Julia这个数组的最佳迭代顺序是什么?问题开始了:
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
julia> @which R[Int8(1),Int8(1)]
getindex(A::AbstractArray, I...) in Base at abstractarray.jl:925