strings.SplitSeq în Go

Variantele iterator ale lui Split, SplitAfter, Fields și FieldsFunc, plus Lines: parcurgi bucățile cu for range, fără slice.

Sintaxă
func SplitSeq(s, sep string) iter.Seq[string]
func SplitAfterSeq(s, sep string) iter.Seq[string]
func FieldsSeq(s string) iter.Seq[string]
func FieldsFuncSeq(s string, f func(rune) bool) iter.Seq[string]
func Lines(s string) iter.Seq[string]

Ce face strings.SplitSeq

Din Go 1.24, pachetul strings are funcții care returnează un iterator (iter.Seq[string]) în loc de slice. Le parcurgi direct cu for bucata := range strings.SplitSeq(s, ","). Bucățile sunt aceleași ca la Split, SplitAfter, Fields și FieldsFunc, dar nu se construiește un slice cu toate, deci se folosește mai puțină memorie pe texte mari.

strings.Lines(s) parcurge rândurile textului. Fiecare rând își păstrează caracterul \n de la final (cu excepția ultimului rând, dacă textul nu se termină cu \n). Un text gol nu dă niciun rând.

Iteratoarele sunt de unică folosință: pentru o a doua parcurgere, cheamă funcția din nou. Dacă ai nevoie de un slice (de exemplu pentru len sau acces după poziție), folosește slices.Collect sau funcția clasică.

Parametri

Parametru Descriere
s Textul de parcurs.
sep Separatorul (la SplitSeq și SplitAfterSeq).
f Condiția de despărțire (la FieldsFuncSeq).

Ce returnează

Un iterator iter.Seq[string], folosit cu for … range.

Exemple

Exemplul 1: Etichete separate prin virgulă

package main

import (
	"fmt"
	"strings"
)

func main() {
	etichete := "go, programare,începători ,  română"
	for e := range strings.SplitSeq(etichete, ",") {
		fmt.Printf("[%s]\n", strings.TrimSpace(e))
	}
	for c := range strings.FieldsSeq("  unu  doi   trei ") {
		fmt.Print(c, ";")
	}
	fmt.Println()
}

Rezultat

[go]
[programare]
[începători]
[română]
unu;doi;trei;

Exemplul 2: Lines: rândurile unui text

%q arată că fiecare rând păstrează \n; ultimul rând nu are, pentru că textul nu se termină cu rând nou.

package main

import (
	"fmt"
	"strings"
)

func main() {
	text := "Ana 10\nIon 8\nMaria 9"
	nr := 0
	for rand := range strings.Lines(text) {
		nr++
		fmt.Printf("%d: %q\n", nr, rand)
	}
}

Rezultat

1: "Ana 10\n"
2: "Ion 8\n"
3: "Maria 9"

Exemplul 3: SplitAfterSeq, FieldsFuncSeq și slices.Collect

package main

import (
	"fmt"
	"slices"
	"strings"
	"unicode"
)

func main() {
	parti := slices.Collect(strings.SplitAfterSeq("a/b/c", "/"))
	fmt.Printf("%q, lungime %d\n", parti, len(parti))

	esteSeparator := func(r rune) bool { return !unicode.IsLetter(r) }
	for cuvant := range strings.FieldsFuncSeq("Cluj-Napoca, Iași; Brașov", esteSeparator) {
		fmt.Println(cuvant)
	}
}

Rezultat

["a/" "b/" "c"], lungime 3
Cluj
Napoca
Iași
Brașov

Greșeli frecvente

  • Uiți că rândurile din Lines se termină cu \n și le compari direct cu "Ana 10". Scoate întâi rândul nou cu strings.TrimSuffix(rand, "\n") sau TrimSpace.
  • Încerci len(strings.SplitSeq(...)). Un iterator nu are lungime; folosește strings.Split sau slices.Collect.
  • Folosești aceste funcții cu o versiune de Go mai veche de 1.24: nu compilează.

Comenzi înrudite

  • strings.Split: Împarte textul în bucăți după un separator exact; SplitN limitează numărul de bucăți, SplitAfter păstrează separatorul.
  • strings.Fields: Împarte textul în cuvinte după spații (oricâte, inclusiv tab și rând nou); FieldsFunc după o condiție a ta.
  • strings.Reader: Face dintr-un text o sursă de citire (io.Reader), ca să-l dai funcțiilor care citesc din fișiere sau rețea.