Treci la conținutul principal

Obținerea unui singur element

Această lecție arată cum obții un singur element dintr-un slice: după poziția lui, după o condiție sau la întâmplare. Arată și cum verifici dacă un element există.

Go nu are null. Când o căutare poate eșua, o funcție Go returnează două valori: elementul și un bool numit ok. Este același tipar value, ok pe care îl știi de la map-uri.

Citirea unei poziții care nu există, de exemplu words[5] într-un slice cu 5 elemente, oprește programul cu un panic (o eroare la rulare). De aceea verificăm întotdeauna mai întâi len().

Alte limbaje au multe funcții gata făcute pentru asta. Go păstrează limbajul mic: folosești paranteze pătrate, pachetul slices sau un mic helper pe care îl scrii o singură dată.


Obținerea după poziție

Fiecare element dintr-un slice are o poziție numită index. Primul index este 0, deci ultimul este len(words)-1.

Ca să citești un element după poziție, scrie indexul între paranteze pătrate: words[3]. Așa citește Go elementul de la o poziție, primul element sau ultimul element.

Go nu are elementAtOrNull() sau elementAtOrElse(). Un mic helper generic verifică indexul față de len() și returnează fie value, ok, fie rezultatul unei funcții de rezervă. Astfel, un index în afara intervalului nu poate provoca un panic.

Element de la o poziție

words[3] citește elementul de la indexul 3. Fiindcă numărătoarea începe de la 0, acesta este al patrulea cuvânt.

Prompt
Fă un slice cu cuvintele one, two, three, four, five. Afișează elementul de la indexul 3 folosind parantezele pătrate.
Ieșire: program Go și rezultatul capturat
Element at a position

Primul și ultimul element

Primul element este words[0]. Ultimul este words[len(words)-1], pentru că lungimea este 5, dar ultimul index este 4.

Prompt
Fă un slice cu cuvintele one, two, three, four, five. Afișează primul element folosind indexul 0, apoi ultimul element folosind indexul len minus 1.
Ieșire: program Go și rezultatul capturat
First and last element

Element de la o poziție, sau ok == false

ElementAt verifică indexul față de len(). Indexul 1 este în interval, deci returnează "two" și true. Indexul 5 este în afara intervalului, deci returnează valoarea zero "" și false în loc să provoace un panic.

Prompt
Scrie un helper generic ElementAt care returnează elementul de la un index și true, sau valoarea zero și false atunci când indexul este în afara intervalului. Apelează-l pe cuvintele one, two, three, four, five cu indexul 1 și cu indexul 5 și afișează valoarea între ghilimele împreună cu indicatorul ok.
Ieșire: program Go și rezultatul capturat
Element at a position, or ok == false

Element de la o poziție, sau o valoare de rezervă

ElementAtOrElse primește o funcție de rezervă. Funcția primește indexul, așa că poate construi un mesaj precum „Valoarea pentru indexul 5 este nedefinită”.

Prompt
Scrie un helper generic ElementAtOrElse care returnează elementul de la un index, sau rezultatul unei funcții de rezervă care primește indexul. Apelează-l pe cuvintele one, two, three, four, five cu indexul 5 și cu o funcție de rezervă care construiește textul „Valoarea pentru indexul 5 este nedefinită”. Afișează rezultatul.
Ieșire: program Go și rezultatul capturat
Element at a position, or a fallback

Obținerea după condiție

De multe ori nu știi poziția. În schimb, știi o condiție: primul cuvânt mai lung de 3 litere, ultimul cuvânt care începe cu „f”. Condiția este o funcție care primește un element și returnează true sau false.

Pentru prima potrivire, pachetul slices are slices.IndexFunc(). Returnează indexul primului element care trece testul, sau -1 când niciun element nu îl trece. Apoi citești elementul cu acel index.

În slices nu există o funcție pentru ultima potrivire. O buclă for care numără descrescător de la len(words)-1 găsește ultima potrivire: prima potrivire întâlnită mergând înapoi este ultima din slice.

Dincolo de atât, Go nu are funcții de căutare gata făcute. Micile helpere generice Find și FindLast fac treaba și returnează value, ok, așa că „nu s-a potrivit nimic” înseamnă doar ok == false.

Prima potrivire

slices.IndexFunc() dă indexul primului cuvânt cu len(s) > 3. Acel cuvânt este "three".

Prompt
Fă un slice cu cuvintele one, two, three, four, five. Folosește slices.IndexFunc ca să găsești primul cuvânt mai lung de 3 litere și afișează acel cuvânt.
Ieșire: program Go și rezultatul capturat
First match

Ultima potrivire

Bucla începe de la ultimul index și coboară. Primul cuvânt întâlnit care începe cu "f" este "five", deci bucla îl afișează și se oprește cu break.

Prompt
Fă un slice cu cuvintele one, two, three, four, five. Parcurge slice-ul înapoi, de la ultimul index, și afișează primul cuvânt care începe cu „f”, apoi oprește bucla.
Ieșire: program Go și rezultatul capturat
Last match

Prima potrivire, sau ok == false

Niciun cuvânt nu este mai lung de 6 litere, deci Find returnează ok == false și programul afișează „nu a fost găsit”. În slice-ul cu numere, primul număr par este 2.

Prompt
Scrie un helper generic Find care returnează primul element care îndeplinește o condiție și true, sau valoarea zero și false. Caută în cuvintele one, two, three, four, five un cuvânt mai lung de 6 litere și afișează „nu a fost găsit” când ok este false. Apoi caută în numerele 1, 2, 3, 4 primul număr par și afișează-l.
Ieșire: program Go și rezultatul capturat
First match, or ok == false

Ultima potrivire, sau ok == false

FindLast parcurge numerele înapoi. Ultimul număr par este 4 și este găsit imediat.

Prompt
Scrie un helper generic FindLast care parcurge un slice înapoi și returnează ultimul element care îndeplinește o condiție și true, sau valoarea zero și false. Folosește-l pe numerele 1, 2, 3, 4 ca să găsești ultimul număr par și afișează-l.
Ieșire: program Go și rezultatul capturat
Last match, or ok == false

Obținerea cu un selector

Uneori vrei să transformi mai întâi fiecare element și abia apoi să iei primul rezultat care se potrivește.

Go nu are o astfel de funcție. O buclă for face asta: convertește fiecare element, testează rezultatul și oprește-te cu break la primul rezultat bun. Slice-ul de aici are tipul []any, deci poate conține în același timp un număr, un string și un bool. fmt.Sprint() transformă orice valoare în text.

Prima valoare convertită care se potrivește

Fiecare valoare este transformată în text cu fmt.Sprint(). 0 devine "0", care este prea scurt. "true" are 4 caractere, deci este afișat și bucla se oprește.

Prompt
Fă un slice de tip []any care conține 0, string-ul „true” și false. Transformă fiecare valoare în text cu fmt.Sprint și afișează primul text care are 4 sau mai multe caractere, apoi oprește-te.
Ieșire: program Go și rezultatul capturat
First converted value that fits

Element aleator

Ca să alegi un element aleator, alege un index aleator. Pachetul math/rand dă numere aleatoare; r.Intn(n) returnează un număr de la 0 până la n-1, adică exact intervalul indexurilor valide.

Go nu are o metodă random() pentru slice-uri, deci indexul intră între paranteze pătrate, ca de obicei.

O sursă aleatoare creată cu rand.NewSource(42) pornește de la un seed fix. Cu același seed, programul alege de fiecare dată același element, ceea ce face rezultatul previzibil. Lasă seed-ul deoparte când vrei un rezultat diferit la fiecare rulare.

Alege un element aleator

Cu seed-ul 42, sursa alege indexul 1, deci programul afișează 2. Schimbă seed-ul și poate ieși alt număr.

Prompt
Fă un slice cu numerele 1, 2, 3, 4. Creează o sursă aleatoare inițializată cu seed-ul 42 folosind math/rand, alege un index aleator cu Intn și afișează elementul de la acel index.
Ieșire: program Go și rezultatul capturat
Pick a random element

Verificarea existenței unui element

Ca să verifici dacă o valoare se află într-un slice, folosește slices.Contains(). Returnează true sau false.

Go nu are containsAll(). Un mic helper generic parcurge valorile căutate și apelează slices.Contains() pentru fiecare. Returnează false de îndată ce o valoare lipsește.

Go nu are nici isEmpty(), nici isNotEmpty(). Compară lungimea: len(s) == 0 înseamnă că este gol, len(s) > 0 înseamnă că nu este gol.

Conține o valoare

"four" se află în slice, deci prima verificare este true. "zero" nu se află, deci a doua verificare este false.

Prompt
Fă un slice cu cuvintele one, two, three, four, five. Folosește slices.Contains ca să verifici dacă „four” se află în slice și dacă „zero” se află în slice. Afișează ambele răspunsuri.
Ieșire: program Go și rezultatul capturat
Contains one value

Conține toate valorile

Și "four", și "one" se află în slice, deci ContainsAll returnează true. "zero" lipsește, deci al doilea apel returnează false.

Prompt
Scrie un helper generic ContainsAll care returnează true doar când fiecare valoare dintr-un al doilea slice se găsește în primul slice, folosind slices.Contains. Verifică în cuvintele one, two, three, four, five prezența valorilor four și one, apoi a valorilor one și zero. Afișează ambele răspunsuri.
Ieșire: program Go și rezultatul capturat
Contains all values

Gol sau cu elemente

empty are lungimea 0, deci len(empty) == 0 este true. words are 5 elemente, deci și len(words) > 0 este true.

Prompt
Fă un slice cu cuvintele one, two, three, four, five și un slice gol de string-uri. Afișează dacă lungimea slice-ului gol este 0, apoi dacă lungimea slice-ului cu cuvinte este mai mare decât 0.
Ieșire: program Go și rezultatul capturat
Empty or not empty