Inleiding
In Go zijn arrays en slices gegevensstructuren die uit een geordende reeks elementen bestaan. Deze gegevensverzamelingen zijn erg handig om te gebruiken als je veel gerelateerde waarden wilt werken. Ze stellen je in staat gegevens bijeen te houden die bij elkaar horen, uw code compacter te maken, en dezelfde methodes en bewerkingen op meerdere waarden tegelijk uit te voeren.
Hoewel arrays en slices in Go zowel geordende reeksen van elementen zijn, bestaan er significante verschillen tussen de twee. Een array in Go is een gegevensstructuur die uit een geordende reeks elementen bestaat die haar capaciteit bij de creatie vast is gesteld.一旦 een array zijn grootte is toegewezen, kan de grootte niet meer worden gewijzigd. Een slice, aan de andere kant, is een variant met variabele lengte van een array, die meer flexibiliteit biedt voor ontwikkelaars die deze gegevensstructuren gebruiken. Slices vormen wat je zou kunnen denken van arrays in andere talen.
Given these differences, there are specific situations when you would use one over the other. If you are new to Go, determining when to use them can be confusing: Although the versatility of slices make them a more appropriate choice in most situations, there are specific instances in which arrays can optimize the performance of your program.
Dit artikel zal arrays en slices uitgebreid behandelen, waardoor u de nodige informatie krijgt om de juiste keuze te kunnen maken tussen deze gegevenstypen. Bovendien zult u de meest voorkomende manieren om arrays en slices te declareren en te werken bekijken. Het handleiding zal beginnen met een beschrijving van arrays en hoe u ze kunt manipuleren, gevolgd door een uitleg over slices en hoe ze verschillen.
Arrays
Arrays zijn collectiegegevensstructuren met een vast aantal elementen. Aangezien de grootte van een array statisch is, moet de gegevensstructuur alleen maar eenmaal geheugen toewijzen, in tegenstelling tot een gegevensstructuur met een variabele lengte die dynamisch geheugen moet toewijzen zodat het in de toekomst groter of kleiner kan worden. Hoewel de vast lengte van arrays hen wat flexibel kan maken om mee te werken, kan de eenmalige geheugentoewijzing de snelheid en prestaties van uw programma kunnen verhogen. Door deze reden gebruiken ontwikkelaars arrays meestal wanneer ze programma’s optimaliseren in gevallen waarin de gegevensstructuur nooit een variabele hoeveelheid elementen nodig zal hebben.
Array Definitie
Arrays worden gedefinieerd door de grootte van de array te declareren tussen haakjes [ ]
, gevolgd door het datatype van de elementen. Een array in Go moet alle elementen dezelfde datatype hebben. Na het datatype kunt u de individuele waarden van de array-elementen declareren in curly brackets { }
.
Hieronder is de algemene schema voor de declaratie van een array:
Opmerking: Het is belangrijk om te beseffen dat elke declaratie van een nieuwe array een onderscheidende type maakt. Daarom zijn [2]int
en [3]int
beide int-elementen, maar hun verschillende lengtes maken hun data-typen incompatibel.
Als je de waarden van de array’s elementen niet declareert, worden deze standaard als zerovalueën beschouwd, wat betekent dat de elementen van de array leeg zijn. Voor integers wordt dit 0
representeerd, en voor strings wordt dit een lege string representeerd.
Bijvoorbeeld, de volgende array numbers
heeft drie integer-elementen die nog geen waarde hebben:
Als je numbers
打印 zou, zou je de volgende uitvoer krijgen:
Output[0 0 0]
Als je een variabeel aan de array wilt toevoegen en erop printen, plaats de waarden in curly brackets. Een array met ingestelde waarden ziet er als volgt uit:
Je kan een array in een variabeel storen en erop printen:
Een programma met de vorige lijnen zou de volgende uitvoer geven:
Output[blue coral staghorn coral pillar coral elkhorn coral]
Merk op dat er geenscheiding bestaat tussen de elementen in de array bij het afdrukken ervan, waardoor het soms moeilijk is te bepalen waar een element eindigt en het volgende begint. door dit, helpt het soms om de `fmt.Printf` functie te gebruiken in plaats daarvan, die strings kan formatteren voor ze worden afgedrukt op het scherm. Geef de `%q` parameter aan dit commando om de functie te instructeren om aanhalingstekens om de waarden heen te plaatsen:
Dit zal resulteren in het volgende:
Output["blue coral" "staghorn coral" "pillar coral" "elkhorn coral"]
Nu wordt elk item geciteerd. De `\n` parameter instructeert de formatter om een regel terug te voegen aan het einde.
Met een algemeen idee van hoe array’s worden gedeclareerd en wat ze bestaan uit, kun je nu doorstromen naar het leren hoe elementen in een array worden gespecificeerd met een indexnummer.
Indexeren van Array’s (en Slices)
Elk element in een array (en ook een slice) kan individueel worden aangeroepen via indexering. Elk element correspondeert aan een indexnummer, dat een `int` waarde is die begint bij het indexnummer `0` en oplaatst.
We zullen een array gebruiken in de volgende voorbeelden, maar je kon ook een slice gebruiken, aangezien ze identiek zijn in hoe je beide indexeert.
Voor de array `coral`, ziet de indexindeling er als volgt uit:
“blue coral” | “staghorn coral” | “pillar coral” | “elkhorn coral” |
---|---|---|---|
0 | 1 | 2 | 3 |
De eerste element, de string "blauwe koraal"
, startt bij index 0
en de slicet eindigt bij index 3
met het element "elkhorn koraal"
.
Omdat elk element in een slice of array een bijbehorende indexnummer heeft, kunnen we ze in dezelfde manier aanhalen en manipuleren als met andere sequentiele datatypen.
Nu kunnen we een afzonderlijk element van de slice aanhalen door zijn indexnummer te refereren:
Outputstaghorn coral
De indexnummers voor deze slice vallen binnen 0-3
, zoals geïllustreerd in de vorige tabel. Om daarvan elk individueel element te halen, moeten we zo doen:
Als we de array coral
aanroepen met een indexnummer die groter is dan 3
, wordt dat niet geldig omdat het niet valide zou zijn:
Outputpanic: runtime error: index out of range
Wanneer je een array of slice indexeert, moet je altijd een positieve nummer gebruiken. In sommige talen mag je terugindexeren met een negatief nummer, maar in Go leidt dat tot een fout:
Outputinvalid array index -1 (index must be non-negative)
We kunnen twee string-elementen in een array of slice samenvoegen met behulp van de +
operator:
OutputSammy loves blue coral
We waren in staat om de string-element op indexnummer 0
te samenvoegen met de string "Sammy liefst "
.
Met indexnummers die corresponderen aan elementen binnen een array of slice, kunnen we elk element discreet aanhalen en werken met die elementen. Om dit te demonstreren, zullen we nu kijken hoe je een element op een bepaald index wijzigt.
Elementen aanpassen
We kunnen indexering gebruiken om elementen binnen een array of slice aan te passen door een geindexeerd element gelijk te stellen aan een andere waarde. Dit geeft ons meer controle over de data in onze slices en arrays en zal ons toestaan om individuele elementen programmatisch te manipuleren.
Als we de tekstuele waarde van het element aan de index 1
van de array coral
willen veranderen van "staghorn coral"
naar "foliose coral"
, kunnen we dat doen op de volgende manier:
Nu we coral
afdrukken, zal de array anders zijn:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral"]
Nu dat u weet hoe u individuele elementen van een array of slice kunt manipuleren, kijken we naar een paar functies die u meer flexibiliteit bieden bij het werken met collectiedata types.
Elementen tellen met len()
In Go is len()
een ingebouwde functie die is ontworpen om u te helpen werken met arrays en slices. Net zoals bij strings, kunt u de lengte van een array of slice berekenen door len()
te gebruiken en het array of de slice als parameter mee te geven.
Bijvoorbeeld, om te weten hoeveel elementen er in de coral
-array zitten, zou u gebruik maken van:
Als je de lengte van de array coral
uitprint, krijg je de volgende uitvoer:
Output4
Dit geeft de lengte van de array 4
in het int
datatype, wat juist is omdat de array coral
vier items heeft:
Als je een array met meer elementen maak, kun je ook de len()
functie gebruiken op deze:
Dit zou resulteren in de volgende uitvoer:
Output13
Dankzij deze voorbeelden zijn er relatief weinig items, maar de len()
functie is bijzonder handig wanneer je vastheeft dat zeer grote arrays zijn.
Nu zal ik u laten zien hoe je een element toe kan voegen aan een collectie datatype en demonstreren hoe, omdat arrays statisch zijn en hun lengte niet wordt gewijzigd, toevoegen aan deze statische data types zal resulteren in een fout.
Toevoegen van elementen met append()
append()
is een ingebouwd methode in Go die elementen toevoegt aan een collectie datatype. Maar deze methode werkt niet als je hem gebruikt met een array. Zoals eerder gezegd, de belangrijke manier waarop arrays verschillen van slices is dat de grootte van een array niet wordt verandert nadat hij is definieerd. Dit betekent dat terwijl je de waarden van elementen in een array kunt veranderen, je de grootte van de array niet kunt veranderen naar aanleiding van zijn definitie.
Laten we nu uw coral
-array overwegen:
Om deze item "zwarte koraal"
toe te voegen aan deze array probeer je het met de append()
functie van de array door te typen:
U bent een fout te krijgen als uw uitvoer:
Outputfirst argument to append must be slice; have [4]string
Om dit te corrigeren leer meer over de slicetype data, hoe je een slicedefineert en hoe je van een array naar een slice converteert.
Slices
Een slijt is een datatype in Go die mutable, ofwijzerbaar, geordende serie elementen is. Omdat de grootte van een slijt variabel is, biedt er veel meer flexibiliteit wanneer je met data collecties werkt die mogelijk moeten worden geprofondered of verkleinen; wanneer je veel elementen nodig hebt of je elementen wilt iteratie over en je wilt deze elementen mogelijk modificeren, zou je waarschijnlijk beter gebruik maken van de slijt datatype. Wanneer je veel elementen nodig hebt of je iteratie over elementen wilt en je wilt deze elementen mogelijk modificeren, zou je waarschijnlijk beter gebruiken zijn met de slijt datatype.
Defining a Slice
Slices worden gedefinederd door de datatype te declareren met een lege set van kwartetjes ([]
) en een lijst van elementen tussen curly brackets ({}
). U zal erbij merken dat, in contrast met arrays die een int
nodig hebben tussen de haakjes om een bepaald aantal aan te duiden, een slice geen elementen tussen de haakjes heeft, representeren zijn variabele lengte.
Laten we nu een slice maken die elementen van het typetje string bevat:
Wanneer u de slice打印 uit, ziet u de elementen die in de slice zijn:
Dit zal resulteren in de volgende uitvoer:
Output["shark" "cuttlefish" "squid" "mantis shrimp" "anemone"]
Als je een slice wilt maken met een bepaalde lengte zonder de elementen van de collectie te vullen, kan je gebruik maken van de ingebouwde make()
functie:
Als je dit slice print uit, zoud je het volgende krijgen:
Output["" "" ""]
Je kunt ook de make()
functie gebruiken met een derde argument om de herinneringen voor een bepaalde capaciteit te allocateren:
Dit zou een nulldate slice met een lengte van 3
en een vooralloze capaciteit van 5
elementen maken.
Nu kunt u weten hoe je een slice declareert. Maar dit is nog niet de manier waarop we eerder de fout had met de coral
array. Om de append()
functie met coral
te gebruiken moet u eerst leren hoe je secties van een array slaat.
Slijten Arrays Into Slices
Bij het gebruik van indexnummers om te bepalen welke subsectie van de waarden binnen een array wordt gekozen, wordt dit slicing genoemd van de array. Dit kunt u doen door een reeks indexnummers te gebruiken gescheiden door een komma, in de vorm van [ eerste_index : tweede_index ]
. Het is echter belangrijk te noteren dat bij het snijden van een array, de resultaat een slice is, niet een array.
Laten we zeggen dat je de middelste items van de coral
-array wilt printen, zonder de eerste en laatste element. Je kan dit doen door een slice te maken die begint op index 1
en eindigt net voor index 3
:
Een programma met deze lijn zou de volgende uitvoer geven:
Output[foliose coral pillar coral]
Wanneer je een slice maakt, als in [1:3]
, is het nummer aan de begin van de slice (inclusief), en het tweede nummer is het product van het eerste nummer en het totaal aantal elementen die je wilt retreiveren:
array[starting_index : (starting_index + length_of_slice)]
In deze situatie heb je de tweede element (of index 1) als startpunt ingesteld en heb je twee elementen in totaal gewild:
array[1 : (1 + 2)]
Dit is hoe de berekening eruitziet:
Wat je daarmee bereikt hebt:
Als je het begin of einde van de array als startpunt of einde van de slice wilt instellen, kun je één van de nummers in de array[first_index:second_index]
syntax overschrijven. Voorbeeld: als je de eerste drie items van de array coral
wilt printen, wat zijn "blue coral"
, "foliose coral"
, en "pillar coral"
, typ je:
Output[blue coral foliose coral pillar coral]
Dit printte de beginnen van de array, stopten voor index 3
.
Om alle items aan het einde van een array te inclureren, gebruik je de syntax met inversie:
Dit zou de volgende slice geven:
Output[foliose coral pillar coral elkhorn coral]
Deze sectie besproken hoe je individuele onderdelen van een array kunt aanroepen door er subsecties uit te snijden. Volgens, leer je hoe je hele arrays gebruiken om te converteren naar slices.
Converteren van een Array naar een Slice
Als je een array maak en besluit dat je hem nodig hebt met variabele lengte, kan je hem converteren naar een slice. Om een array te converteren naar een slice, gebruik de slicing-proces wat je in de Slicing Arrays into Slices stap van deze handleiding leerde, alleen nu selecteer je de hele slice door bij beide indexnummers te omitteren die zouden de eindpunten definieren:
Houd in minde dat je de variabele coral
niet zelf naar een slice kon converteren, omdat een variabele in Go definieerd wordt, haar type niet kan veranderen. Om hierom te werken, kopieer je de hele inhoud van de array naar een nieuwe variabele als een slice:
Als je coralSlice
打印te, zou je de volgende uitvoer ontvangen:
Output[blue coral foliose coral pillar coral elkhorn coral]
Nu probeer je de black coral
element als in de array sectie, gebruik append()
met de nieuw geconverteerde slice:
Dit zal de slice met de toegevoegde element uitprinten:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral"]
We kunnen ook meer dan één element toevoegen in een enkele append()
-oproep:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral" "antipathes" "leptopsammia"]
Om twee slices samen te voegen, kun je append()
gebruiken, maar je moet de tweede argument uitbreiden met de ...
expansie syntaxis om de tweede slice toe te voegen:
Output["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral" "antipathes" "leptopsammia" "massive coral" "soft coral"]
Nu dat je leert hoe je een element aan je slice toevoegt, zal ik u laten zien hoe je er een afhaalt.
Element verwijderen uit een slice
In contrast met andere talen, biedt Go geen ingebouwde functies voor het verwijderen van een element uit een slice. Itemnen moeten worden geknipt en samengesteld met de nieuwe slices zonder het element dat je wilt verwijderen.
Om een element te verwijderen, moet je twee nieuwe slices knippen; knippen van de items voor dat element en knippen van de items na dat element, en daarna appenden die twee nieuwe slices samen zonder het element dat je verwijderen wilde.
Als i
de index is van het te verwijderen element, ziet deze procesvolgorde er als volgend uit:
Van coralSlice
, laat’s het item "elkhorn coral"
verwijderen. Dit item is gelegen op de index positie van 3
.
Output["blue coral" "foliose coral" "pillar coral" "black coral" "antipathes" "leptopsammia" "massive coral" "soft coral"]
Nu is het element op indexpositie 3
, de string "elkhorn coral"
, niet meer in onze slice coralSlice
.
We kunnen ook een reeks verwijderen met dezelfde aanpak. zeggen we willen het item "elkhorn coral"
, maar ook "black coral"
en "antipathes"
verwijderen. We kunnen een reeks gebruiken in de expressie om dit te bewerkstelligen:
Dit code zal index 3
, 4
en 5
van de slicen verwijderen:
Output["blue coral" "foliose coral" "pillar coral" "leptopsammia" "massive coral" "soft coral"]
Nu dat we weten hoe we elementen kunnen toevoegen en verwijderen uit een slicen, laten we kijken hoe we de hoeveelheid gegevens een slicen kan bevatten op elk gegeven moment.
Meet de Capaciteit van een Slicen met cap()
Omdat slicen een variabele lengte hebben is de len()
methode niet de beste optie om de grootte van dit gegevenstype te bepalen. In plaats daarvan kun je de cap()
functie gebruiken om de capaciteit van een slicen te ontdekken. Dit zal aan显示 hoeveel elementen een slicen kan bevatten, die bepaald wordt door hoeveel geheugen al is toegewezen aan de slicen.
Opmerking: Omdat de lengte en de capaciteit van een array altijd hetzelfde zijn, zal de cap()
functie niet werken op arrays.
Een algemeen gebruik van cap()
is het maken van een slicen met een vooraf ingestelde aantal elementen en dan die elementen programmatisch in te vullen. dit voorkomt eventuele onnodige allocaties die kunnen optreden door append()
te gebruiken om elementen toe te voegen buiten de huidige gealloceerde capaciteit.
Als je een lijst van getallen wilt maken, 0
tot en met 3
, kun je gebruiken append()
in een lus, of je kan eerst de slicetje voorbereiden en daarna de lus gebruiken om de waarden te vullen.
Eerst kijken we naar het gebruik van append()
:
Output[0 1 2 3]
In dit voorbeeld hebben we een slicetje gemaakt en dan hebben we een for
-lus gecreeerd die zou iteratief doorlopen over elk van de vier loopvariabelen i
. Elke keer wordt de huidige waarde van de loopvariabele i
toegevoegd aan de index van het slicetje nummers
. Maar dit kan leiden tot onnodig geheugenallozen dat je programma langzamer uitvoert. Wanneer je aan een leeg slicetje toevoegt, checkt de programma elke keer de capaciteit van de slicetje. Als de toegevoegde elementen deze capaciteit overschrijden, maakt de programma extra geheugen aan voor het accounteren hiervan. Dit leidt tot extra overhead in je programma en kan resulteren in een sneller uitvoering.
Nu laten we het slaatje populeren zonder append()
door een bepaalde lengte/capaciteit te voorbereiden:
Output[0 1 2 3]
In dit voorbeeld hebben we make()
gebruikt om een slicetje te maken en hebben we cap()
gebruikt in de lus om door elk van de ingevuld geworden elementen te iteratief lopen, elk totdat het bij de voorbereide capaciteit kwam. In elke lus plaatsen we de huidige waarde van de loopvariabele i
in de index van het slicetje nummers
.
Wanneer de append()
en de cap()
strategieën functieel gelijkwaardig zijn, maakt de cap()
voorbeeld gebruik van geen extra memorieallocaties die nodig zouden zijn als je de append()
functie gebruikt had.
Bouwen aan meerdimensionale snijden
Je kunt ook snijden definieren die bestaan uit andere snijden, met elke lijst tussen haakjes die binnen de groter haakjes van de ouder snijden zijn gevoegd. Zoals deze worden meerdimensionele snijden genoemd. Dit kan gedacht worden als een tweedimensionele coördinatenboom; bijvoorbeeld, een collectie van vijf snijden die elk zeven elementen lang zijn kan representeren als een tweedimensionele grid met horizontale lengte van vijf en verticale hoogte van zeven.
Laten we het volgende meerdimensionele snijden onderzoeken:
Om een element te accessen binnen deze structuur moet je meerdere indexen gebruiken, één voor elke dimensie van de construct:
In de vorige code gebruiken we eerst de element op index 0
van de snijden op index 1
, dan we gebruiken we de element op index 0
van de snijden op index 0
. Dit zal resulteren in het volgende:
OutputSammy
shark
De volgende zijn de index waarden voor de overige individuele elementen:
Bij het werken met meerdimensionale slicen is het belangrijk om te beseffen dat je meer dan één indexnummer nodig hebt om specifieke elementen te accessen binnen de relevante nested slice.
Conclusie
In deze handleiding heb je de fundamenten geleerd over het werken met array’s en slices in Go. Je hebt meerdere oefeningen gedoneerd om te demonstreren hoe arrays fixe lengte zijn, terwijl slices variabele lengte zijn, en hoe dit verschil effectief gebruikt wordt bij de situatievraagstukken van deze data structuren.
Om verder te studeren over data structuren in Go, kijk dan naar onze artikel Het begrip van Maps in Go, of bezoek de hele Hoe Te Coderen in Go-serie.
Source:
https://www.digitalocean.com/community/tutorials/understanding-arrays-and-slices-in-go