You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An example is added to the iter package comment featuring:
A stack-allocated iterator based on struct
Demonstrates an iterator for reading lines from a file
handling of state, error and panic
separating consuming the iterator from data retrieval
the code design used for every other problem solved by Go
Text added to package comment:
Iterators with complex datasource
Iterators encapsulating complex datasources offer value by separating
the iterator consumer from data-retrieval concerns in terms of databases,
networking and file systems. Intra-thread iteration over a function means
additional freedom in designing the iterator for concurrency, synchronization
and threading.
There are four needs on such iterators, referring to the below example:
Receive and maintain internal state: filename, errp, osFile
Provide iteration values and determine end of iteration: [LineReader.Lines]
Release resources upon end of iteration or panic: [LineReader.cleanup]
Propagate error conditions outside the for statement: errp
The below construct ensures faster stack allocation, as opposed to on the heap,
and features potentially reusable iterator-state encapsulated in struct.
The code example (formatted for package comment):
funcExample() {
// errorHandler prints error message and exits 1 on errorvarerrerrordefererrorHandler(&err)
// create test filevarfilename=filepath.Join(os.TempDir(), "test.txt")
iferr=os.WriteFile(filename, []byte("one\ntwo\n"), 0o600); err!=nil {
return
}
// iterate over lines from test.txt// - first argument shows iterator allocated on the stack// - second argument shows providing data to iterator// - third argument shows receiving error from iterator// - —// - stack allocation is faster than heap allocation// - LineReader is on stack even if NewLineReader is in another module// - LineReader pointer receiver is more performantforline:=rangeNewLineReader(&LineReader{}, filename, &err).Lines {
fmt.Println("iterator line:", line)
}
// return here, err may be non-nil// Output:// iterator line: one// iterator line: two
}
// LineReader provides an iterator reading a file line-by-linetypeLineReaderstruct {
// the file lines are being read fromfilenamestring// a pointer to store occurring errorserrp*error// the open fileosFile*os.File
}
// NewLineReader returns an iterator over the lines of a file// - [LineReader.Lines] is iterator function// - new-function provides LineReader encapsulationfuncNewLineReader(fieldp*LineReader, filenamestring, errp*error) (lineReader*LineReader) {
iffieldp!=nil {
lineReader=fieldplineReader.osFile=nil
} else {
lineReader=&LineReader{}
}
lineReader.filename=filenamelineReader.errp=errpreturn
}
// Lines is the iterator providing text-lines from the file filename// - defer cleanup ensures cleanup is executed on panic// in Lines method or for block// - cleanup updates *LineReader.errpfunc (r*LineReader) Lines(yieldfunc(linestring) (keepGoingbool)) {
varerrerrordeferr.cleanup(&err)
ifr.osFile, err=os.Open(r.filename); err!=nil {
return// i/o error
}
varscanner=bufio.NewScanner(r.osFile)
forscanner.Scan() {
if!yield(scanner.Text()) {
return// iteration canceled by break or such
}
}
err=scanner.Err()
// reached end of file or error
}
// LineReader.Lines is iter.Seq stringvar_ iter.Seq[string] = (&LineReader{}).Lines// cleanup is invoked on iteration end or any panic// - errp: possible error from Linesfunc (r*LineReader) cleanup(errp*error) {
varerrerrorifr.osFile!=nil {
err=r.osFile.Close()
}
iferr!=nil||*errp!=nil {
// aggregate errors in order of occurrence*r.errp=errors.Join(*r.errp, *errp, err)
}
}
// errorHandler prints error message and exits 1 on error// - deferrablefuncerrorHandler(errp*error) {
varerr=*errpiferr==nil {
return
}
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
The text was updated successfully, but these errors were encountered:
not a proposal as there's no API changes.
but I think this looks generally out of scope for a package example? it lacks clarity in demonstrating the core concepts of iter.
Proposal Details
An example is added to the iter package comment featuring:
Text added to package comment:
The code example (formatted for package comment):
The text was updated successfully, but these errors were encountered: