Introduzione
In Go, array e slice sono strutture dati che consistono in una sequenza ordinata di elementi. Questi insiemi di dati sono grandiose da utilizzare quando si vuole lavorare con molti valori relazionati. Permettono di tenere insieme i dati che appartengono insieme, comprimendo il codice e eseguendo gli stessi metodi e operazioni su molti valori contemporaneamente.
Anche se array e slice in Go sono entrambe sequenze ordinate di elementi, ci sono differenze significative tra i due. Un array in Go è una struttura dati che consiste in una sequenza ordinata di elementi con la sua capacità definita al momento della creazione. Una volta che l’array ha allocato la sua dimensione, la dimensione non può più essere cambiata. Un slice, d’altro canto, è una versione a lunghezza variabile di un array, fornendo maggiore flessibilità ai sviluppatori che utilizzano queste strutture dati. I slice costituiscono ciò che si potrebbe pensare come array in altre lingue.
Data questa differenza, ci sono situazioni specifiche in cui scegliere uno piuttosto che l’altro. Se sei nuovo in Go, determinare quando usarli può essere confuso: anche se la versatilità degli slice la rende una scelta più appropriata in molte situazioni, ci sono istanze in cui gli array possono ottimizzare il rendimento del tuo programma.
Questo articolo tratterà in dettaglio gli array e le slice, fornendovi le informazioni necessarie per scegliere correttamente tra questi tipi di dati. Inoltre, revisionerai le modalità più comuni per dichiarare e lavorare con sia gli array che le slice. Il tutorial prima descriverà gli array e come manipolarli, poi spiegherà le slice e le loro differenze.
Gli Array
Gli array sono strutture di dati di collezione con un numero fisso di elementi. Poiché la dimensione di un array è statica, la struttura dati ha bisogno di allocare memoria solo una volta, invece di una struttura a lunghezza variabile che deve allocare memoria in maniera dinamica così da potersi allargare o ridurre in futuro. Anche se la lunghezza fissa degli array può rendere il loro utilizzo un po ‘ rigido, l’allocazione memoria unica può aumentare la velocità e il rendimento del programma. A causa di ciò, i developer solitamente usano gli array quando si ottimizza i programmi in casi in cui la struttura dati non avrà mai un numero di elementi variabile.
Dichiarazione di un Array
Gli array sono definiti dichiarando la dimensione dell’array in parentesi quadre [ ]
, seguiti dal tipo di dati degli elementi. Un array in Go deve avere tutti gli elementi della stessa data type. Dopo il tipo di dati, è possibile dichiarare i valori individuali degli elementi dell’array in parentesi graffe { }
.
Il seguente è lo schema generale per la dichiarazione di un array:
Nota: È importante ricordare che ogni dichiarazione di un nuovo array crea un tipo distinto. Quindi, sebbene [2]int
e [3]int
entrambi abbiano elementi interi, la loro lunghezza differisce, rendendo i loro tipi di dati incompatibili.
Se non si dichiara il valore degli elementi dell’array, il default è valorizzato a zero, il che significa che gli elementi dell’array saranno vuoti. Per gli interi, questo è rappresentato da 0
, e per le stringhe questo è rappresentato da una stringa vuota.
Per esempio, l’array numbers
seguente ha tre elementi interi che non hanno ancora un valore:
Se si stampasse numbers
, si riceverebbe l’output seguente:
Output[0 0 0]
Se si desidera assegnare i valori degli elementi all’atto della creazione dell’array, i valori vanno messi nelle parentesi graffe. Un array di stringhe con valori predefiniti si presenta così:
È possibile memorizzare un array in una variabile e stamparlo:
Eseguendo un programma con le righe precedenti si otterrebbe l’output seguente:
Output[blue coral staghorn coral pillar coral elkhorn coral]
Notice che non c’è nessuna delimitazione tra gli elementi dell’array quando viene stampato, rendendo difficile capire dove un elemento termina e l’altro inizia. A causa di ciò, a volte è utile usare la funzione fmt.Printf
invece, che può formattare le stringhe prima di stamparle sullo schermo. Fornire il verbo %q
con questo comando per istruire la funzione a mettere le virgoletto intorno ai valori:
Questo risulterà nel seguente:
Output["blue coral" "staghorn coral" "pillar coral" "elkhorn coral"]
Ora ogni elemento è citato. Il verbo \n
istruisce al formattatore di aggiungere un ritorno a capo alla fine.
Con un’idea generale di come dichiarare array e cosa consistono, ora puoi passare all’apprendimento di come specificare elementi in un array con un numero di indice.
Indicizzare Array (e Slices)
Ogni elemento in un array (e anche in una slice) può essere chiamato individualmente tramite indicizzazione. Ogni elemento corrisponde a un numero di indice, che è un valore di int
che parte dalla numerazione dell’indice 0
e si conta fino in alto.
Utilizzeremo un array nei seguenti esempi, ma potresti usare anche una slice, poiché sono identiche nella loro indicizzazione.
Per l’array coral
, la decomposizione dell’indice è simile a questo:
“blue coral” | “staghorn coral” | “pillar coral” | “elkhorn coral” |
---|---|---|---|
0 | 1 | 2 | 3 |
Il primo elemento è il valore
Dato che ogni elemento di una sezione o un array ha un numero di indice corrispondente, abbiamo la possibilità di accedere e manipolare le loro singole unità come farebbero con altri tipi di dati sequenziali.
Ora possiamo chiamare un elemento discreto della sezione indicando il suo numero di indice:
Outputstaghorn coral
I numeri di indice per questa sezione si spaziano da
Se chiamiamo l’array
Outputpanic: runtime error: index out of range
Quando si indica un array o una sezione, non è consentito usare un numero negativo; facendo così si verificherà un errore:
Outputinvalid array index -1 (index must be non-negative)
Possiamo concatenare gli elementi delle stringhe in un array o in una sezione con altri valori stringa utilizzando il operatore
OutputSammy loves blue coral
Ho concatenato l’elemento della stringa all’indice numero
Con i numeri di indice che corrispondono agli elementi all’interno di un array o sezione, abbiamo la possibilità di accedere ad ogni elemento discretamente e lavorarci con quegli elementi. Per dimostrarlo, prossimamente vedremo come modificare un elemento a un certo indice.
Modificare Elementi
Possiamo usare l’indicizzazione per cambiare gli elementi all’interno di un array o di una slice impostando un elemento numerato per indice uguale ad un valore diverso. Ciò ci dà un maggior controllo sulle informazioni negli array e nelle slice, e ci permetterà di manipolare in modo programmatico gli elementi individuali.
Se vogliamo cambiare il valore stringa dell’elemento all’indice 1
dell’array coral
da "staghorn coral"
a "foliose coral"
, possiamo farlo così:
Ora, quando stampiamo coral
, l’array sarà diverso:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral"]
Adesso che sappiamo come manipolare gli elementi individuali di un array o di una slice, guardiamo the due funzioni che ci daranno maggiore flessibilità quando si lavora con i tipi di dati di collezione.
Conteggio Elementi con len()
In Go, len()
è una funzione integrata creata per aiutarti a lavorare con array e slice. Come per le stringhe, puoi calcolare la lunghezza di un array o di una slice usando len()
e passando l’array o la slice come parametro.
Ad esempio, per capire quanti elementi ci sono nell’array coral
, userai:
Se stampi la lunghezza dell’array coral
, riceverai l’output seguente:
Output4
Questo indica che la lunghezza dell’array coral
è pari al tipo di dati int
, che è corretto perché l’array coral
ha quattro elementi:
Se crei un array di interi con più elementi, potresti usare anche la funzione len()
su questo:
Questo risulterà nel seguente output:
Output13
Tuttavia, questa funzione è particolarmente utile quando si desidera determinare quanti elementi sono presenti in grandi array.
Successivamente, verremo a capire come aggiungere un elemento ad una collezione dati e mostraremo come, a causa della lunghezza fissa degli array, aggiungere elementi alla fine di questi tipi di dati statici risulterà in un errore.
Aggiungendo Elementi con append()
append()
è un metodo predefinito in Go che aggiunge elementi a una collezione dati. Tuttavia, questo metodo non funzionerà quando viene utilizzato con un array. Come spiegato prima, il principale modo in cui gli array differiscono dai slice è che la dimensione di un array non può essere modificata dopo che è stata definita. Ci significa che se puoi cambiare i valori degli elementi all’interno di un array, non puoi farlo diventare più grande o più piccolo dopo che è stato definito.
Considerate il tuo array coral
:
Vogliamo aggiungere l’elemento "black coral"
a questo array. Se provate a usare la funzione append()
con l’array digitando:
Riceverete un errore come output:
Outputfirst argument to append must be slice; have [4]string
Per correggere questo, impareremo di più sul tipo di dato slice, come definire una slice e come convertire un array in una slice.
Slices
Un slice è un tipo di dato in Go che è una mutable, o cambiabile, sequenza ordinata di elementi. Poiché la dimensione di una slice è variabile, ci sono molte più flessibilità quando le usate; quando si lavora con collezioni di dati che potrebbero bisogno di ampliarsi o contrarre in futuro, l’uso di una slice garantirà che il tuo codice non si imbatti in errori quando si tenta di manipolare la lunghezza della collezione. In gran parte, questa mutabilità è giustificata dalla possibile riallocazione della memoria richiesta occasionalmente da slice quando si confrontano con gli array. Quando hai bisogno di memorizzare molti elementi o iterare su elementi e vuoi essere in grado di modificare facilmente quegli elementi, probabilmente vuoi lavorare con il tipo di dato slice.
Defining a Slice
Le slice sono definite dichiarando il tipo di dati preceduto da un set vuoto di parentesi quadre ([]
) e una lista di elementi tra le parentesi curli ({}
). Notare che, rispetto agli array che richiedono un int
tra le parentesi per definire un determinato numero di elementi, la slice non ha nulla tra le parentesi, rappresentando la sua lunghezza variabile.
Possiamo ora creare una slice che contenga elementi del tipo stringa:
Quando stampiamo la slice, notiamo che gli elementi che sono nell’array sono:
Questo sarà risultato nel seguente:
Output["shark" "cuttlefish" "squid" "mantis shrimp" "anemone"]
Se vuoi creare una slice di un certo numero di elementi senza popolare ancora i valori della collezione, puoi usare la funzione predefinita make()
:
Se fosse stato stampato questo slice, avreste ricevuto:
Output["" "" ""]
Se vuoi allocare la memoria per una capacità specificata, puoi passare un terzo argomento alla funzione make()
:
Cosa farebbe una slice con lunghezza di 3
e una capacità preallocata di 5
elementi.
Ora sappiamo come dichiarare una slice. Tuttavia, questo non risolve ancora l’errore che abbiamo avuto con l’array coral
prima. Per usare la funzione append()
con coral
, dovrai prima imparare come tagliare sezioni di array.
Tagliare Array in Slice
Utilizzando i numeri di indice per determinare gli endpoint, puoi chiamare una sezione subordinata delle valeurs all’interno di un array. Questo è chiamato slicing l’array e puoi fare questo creando un range di numeri di indice separati da una colonna, nella forma di
Diciamo che vuoi stampare solo le voci intermedie dell’array coral
, senza l’elemento prima e l’ultimo. Puoi farlo createndo una sottovariabile che inizia al numero
Eseguire un programma con questa linea mostrera il seguente:
Output[foliose coral pillar coral]
Quando si crea una sottovariabile, come in [1:3]
, il primo numero è il punto di partenza (inclusivo), e il secondo numero è la somma del primo numero e del totale degli elementi che desideri recuperare:
array[starting_index : (starting_index + length_of_slice)]
Nel caso specifico, hai chiamato il secondo elemento (o indice 1) come punto di partenza e hai chiesto due elementi in totale. Così facendo, questo è come calcolare:
array[1 : (1 + 2)]
Che è come arrivare a questa notazione:
Se vuoi imprimerli i primi tre elementi dell’array coral
— che saranno "blue coral"
, "foliose coral"
, e "pillar coral"
— puoi fare così:
Questo ti stampera:
Output[blue coral foliose coral pillar coral]
Questo ha stampato l’inizio dell’array, fermandosi appena prima dell’indice 3
.
Per includere tutti gli elementi alla fine di un array, usare la sintassi di inversione:
Questo avrebbe dato il seguente intervallo:
Output[foliose coral pillar coral elkhorn coral]
Questa sezione ha discusso su come chiamare singoli elementi di un array tramite segmentazione. Successivamente, imparare come convertire interi array in segmenti.
Conversione da un Array ad uno Slice
Se crei un array e decidi che hai bisogno di una lunghezza variabile, puoi convertirlo in un segmento. Per convertire un array in un segmento, usa il processo di segmentazione che hai imparato nell’istruzione Segmentazione degli Array. Ma questa volta selezionate tutto il segmento ommettendo entrambi i numeri che determinano le estremità:
Ricorda che non puoi convertire la variabile coral
in un segmento stesso, poiché una volta definita in Go, il tipo di variabile non può essere cambiato. Per evitare questo problema, potresti copiare tutti i contenuti dell’array in una nuova variabile come segmento:
Se fosse stato stampato coralSlice
, riceverete il seguente output:
Output[blue coral foliose coral pillar coral elkhorn coral]
Ora tenta di aggiungere l’elemento black coral
come nell’sezione array, usando append()
con il nuovo convertito segmento:
Questo sarà stampato il segmento con l’elemento aggiunto:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral"]
Potremmo aggiungere anche più di un elemento in una singola istruzione append()
:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral" "antipathes" "leptopsammia"]
Per combinare due slice insieme, puoi usare append()
, ma devi estendere il secondo argomento da aggiungere usando la sintassi di espansione ...
:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral" "antipathes" "leptopsammia" "massive coral" "soft coral"]
Ora che hai imparato come aggiungere un elemento alla tua slice, guarderemo come rimuoverne uno.
Rimuovere un Elemento da una Slice
A differenza di altre lingue, Go non fornisce alcuna funzione interna per rimuovere un elemento da una slice. Gli elementi devono essere rimossi dalla slice tagliandoli.
Per rimuovere un elemento, devi tagliare gli elementi prima di quello e dopo di esso, poi appendere questi due nuovi slice insieme senza l’elemento che vuoi rimuovere.
Se i
è l’indice dell’elemento da rimuovere, allora il formato di questo processo sarà simile al seguente:
Da coralSlice
, rimuoviamo l’elemento "elkhorn coral"
. Questo elemento si trova all’indice posizione 3
.
Output["blue coral" "foliose coral" "pillar coral" "black coral" "antipathes" "leptopsammia" "massive coral" "soft coral"]
Ora l’elemento all’indice posizione 3
, la stringa "elkhorn coral"
, non è più nella nostra slice coralSlice
.
Potrebbe anche eliminare un intervallo con la stessa approccia. Supponiamo che vogliamo rimuovere non solo l’elemento "elkorn corallo"
, ma anche "nero corallo"
e "antipathes"
. Possiamo usare una espressione di range per fare questo:
Questa espressione si comporterà come se fosse stato utilizzato un range nell’espressione:
Output["blue coral" "foliose coral" "pillar coral" "leptopsammia" "massive coral" "soft coral"]
Ora che sappiamo come aggiungere e rimuovere elementi da una slice, guardiamo ora come misurare quanto dati può contenere una slice al momento attuale.
Misura della capacità di una slice con cap()
Dato che le slice possono avere lunghezze variabili, il metodo len()
non è l’opzione migliore per determinare la dimensione di questo tipo di dato. Invece, puoi usare la funzione cap()
per sapere quanti elementi può contenere una slice. Questo mostrera ai tuoi risultati quanto memoria è già stata allocata per la slice.
Nota: Perché la lunghezza e la capacità di un array sono sempre uguali, la funzione cap()
non funzionerà su array.
Un uso comune per cap()
è quello di creare una slice con un numero predefinito di elementi e poi riempirli elementi programmaticamente. Questo evita potenzialiallocazioni inutili che potrebbero accadere se usassi append()
per aggiungere elementi oltre la capacità attualmente allocata.
Il caso di esempio che vogliamo considerare è quello in cui vogliamo creare un elenco di numeri da
Prima, guardiamo l’esempio di utilizzo di
Output[0 1 2 3]
Nell’esempio precedente abbiamo creato una sezione e poi abbiamo creato un
Ora popoliamo la sezione senza usare
Output[0 1 2 3]
Nel nostro esempio abbiamo usato
Mentre le funzioni append()
e cap()
sono entrambe funzionalmente equivalenti, l’esempio di cap()
evita ogni allocazione di memoria aggiuntiva che sarebbero state necessarie usando la funzione append()
.
Slicing Multidimensionale
Puoi anche definire tagli che consistono in altri tagli come elementi, con ogni elenco racchiuso all’interno delle parentesi maggiori del taglio padre. Le collezioni di questo tipo si chiamano tagli multidimensionali. Questi possono essere considerati come rappresentazioni delle coordinate multidimensionali; ad esempio, una raccolta di cinque tagli ognuno lungo sei elementi potrebbe rappresentare un griglia bidimensionale con lunghezza orizzontale di cinque e altezza verticale di sei.
Esaminiamo il seguente taglio multidimensionale:
Per accedere ad un elemento all’interno di questo taglio, dovremmo usare indici multipli, uno per ogni dimensione della costruzione:
Nel codice precedente, prima identifica l’elemento all’indice 0
del taglio all’indice 1
, poi indica l’elemento all’indice 0
del taglio all’indice 0
. Questo avverra il seguente risultato:
OutputSammy
shark
I valori degli indici per gli altri elementi singoli sono i seguenti:
Quando si lavora con sottili slice multidimensionali, è importante tenere a mente che sarà necessario riferirsi a più di un numero di indice per accedere agli elementi specifici all’interno del slice nested relativo.
Conclusione
In questo tutorial, hai imparato i fondamenti del lavoro con array e slice in Go. Hai attraversato molti esercizi per dimostrare come gli array hanno una lunghezza fissa, mentre le slice hanno una lunghezza variabile, e hai scoperto come questa differenza influenza l’utilizzo delle strutture dati in determinate situazioni.
Per continuare a studiare le strutture dati in Go, consulta il nostro articolo su Comprendere le Mappe in Go, o esplora l’intera serie Come Programmare in Go.
Source:
https://www.digitalocean.com/community/tutorials/understanding-arrays-and-slices-in-go