Quero saber o que funciona
func formIndex(after i: inout Int)
De acordo com a documentação diz:
Substitui o índice fornecido pelo seu sucessor.
Mas se tentarmos imprimir os índices depois de usar essa função, eles não mudarão:
var arr = [1,5,10, 15]
var index = arr.startIndex
arr.indices.forEach { index in
print("before form index \(index)")
}
arr.formIndex(after: &index)
arr.indices.forEach { index in
print("after form index \(index)")
}
Saída:
before form index 0
before form index 1
before form index 2
before form index 3
after form index 0
after form index 1
after form index 2
after form index 3
Ficou ainda mais confuso quando tentei imprimir o valor naquele índice:
var arr = [1,5,10, 15]
var index = arr.startIndex
arr.indices.forEach { index in
print("before form index \(index)")
}
print("index is \(index)")
print("arr zero index value before form index \(arr[0])")
print("arr first index value before form index \(arr[1])")
print("arr index value before form index \(arr[index])")
arr.formIndex(after: &index)
arr.indices.forEach { index in
print("after form index \(index)")
}
print("arr zero index value after form index \(arr[0])")
print("arr first index value after form index \(arr[1])")
print("arr index value after form index \(arr[index])")
Saída:
before form index 0
before form index 1
before form index 2
before form index 3
index is 0
arr zero index value before form index 1
arr first index value before form index 5
arr index value before form index 1
after form index 0
after form index 1
after form index 2
after form index 3
arr zero index value after form index 1
arr first index value after form index 5
arr index value after form index 5
Parece que mesmo index
o valor é 0
, temos resultados diferentes para o valor em arr[0]
e arr[index]
.
Você entendeu errado o que
formIndex(after:)
faz. Ele não modifica o array de forma alguma (ele não é marcado commutating
afinal). Tudo o que ele faz é definir oinout
parâmetro que você passou, para o próximo índice. Aqui está uma demonstração:index
é inicialmente 0. Depois que você o passa paraformIndex(after:)
, ele se torna 1, porque 1 é o próximo índice depois de 0. Isso é tudo o que ele faz.No texto da documentação, "substitui o índice fornecido" refere-se à definição do
inout
parâmetro para um valor diferente, e "seu sucessor" refere-se a um índice , não a um elemento na matriz.Por que tal método seria útil? Certamente, raramente é útil chamar isso em um
Array
. Para obter o próximo índice de umArray
, você pode simplesmente adicionar 1. Mas se você estiver trabalhando com um arbitrárioCollection
(escrevendo código genérico ), isso é muito útil. Um arbitrárioCollection
não usa necessariamente uma sequência incremental deInt
s como seus índices. Por exemplo,Dictionary
é umCollection
, e ele usaDictionary.Index
valores como seus índices.Portanto, o objetivo do
formIndex(after:)
é fornecer uma maneira de encontrar o próximo índice de um determinado índice para qualquerCollection
.Como exemplo, isso é usado na implementação de
firstIndex(of:)
:Na verdade, você precisa implementar um método similar -
index(after:)
- ao se conformar aoCollection
protocolo. A implementação padrão deformIndex(after:)
definirá oinout
parâmetro para o queindex(after:)
for retornado.Você pode pensar em
formIndex(after:)
apenas uma versão "in-place" deindex(after:)
. Ao usar uminout
parâmetro, o compilador pode otimizá-lo para uma passagem por referência (como se estivesse pegando um ponteiro), o que evita copiar o valor do índice. Como o tipo de índice pode ser um tipo arbitrário, copiar o valor do índice pode ser caro.