Proposal Details
Once iterators are introduced in 1.23 there is growing number of libraries based on this feature. Reading data by lines or words are quite common task and could be accomplished with for ... range
loop. It requires just two simple methods for bufio.Scanner
:
func (s *Scanner) TextSeq() iter.Seq[string] {
return func(yield func(string) bool) {
for s.Scan() {
if !yield(s.Text()) {
break
}
}
}
}
func (s *Scanner) BytesSeq() iter.Seq[[]byte] {
return func(yield func([]byte) bool) {
for s.Scan() {
if !yield(s.Bytes()) {
break
}
}
}
}
Reading whole file as collection of lines could be like:
f, err := os.Open("file.txt")
if err != nil {
panic(err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
// read all lines as slice of strings
lines := slices.Collect(scanner.TextSeq())
// instead of:
// lines := make([]string, 0)
// for scanner.Scan() {
// lines = append(lines, scanner.Text())
// }
Comment From: gabyhelp
Related Issues
- bufio: reading lines is too cumbersome #4802 (closed)
- bufio: can improve bufio.Scanner and bufio.Reader for bytes.Reader and strings.Reader #11655 (closed)
Related Documentation
Related Discussions
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: seankhliao
this doesn't address how errors should be surfaced, see #70084 for related discussion
Comment From: mateusz834
Also why global functions, instead of methods?
Comment From: pkierski
Also why global functions, instead of methods?
My bad, I've copied code from my experiments. I've thought about method ofc.
Comment From: mateusz834
this doesn't address how errors should be surfaced, see https://github.com/golang/go/issues/70084 for related discussion
And #70631
Comment From: earthboundkid
I think the naming convention is BytesSeq
, like strings.SplitSeq etc. in 1.24.
Comment From: pkierski
I think the naming convention is
BytesSeq
, like strings.SplitSeq etc. in 1.24.
Thank you, changed according to this suggestion.
Comment From: adonovan
The need to remember to call Scanner.Err after iterating, even with the traditional API, is already a problem; iterators may make it even easier to forget to do so. I think we should put this proposal aside until we have a consensus on how to deal with iterable sequences with the potential for errors. In the meantime, you can always write this function yourself.
Comment From: aclements
It's unfortunate that errors and iterators mix poorly, but @adonovan is right that iterators are sometimes not quite the right solution.
Comment From: aclements
Based on the discussion above, this proposal seems like a likely decline. — aclements for the proposal review group
Comment From: aclements
No change in consensus, so declined. — aclements for the proposal review group