-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: iter: add Empty function #66187
Comments
I know the code is contrived as an example, but couldn't you rewrite it as if cond {
if all := findAll(); all != nil {
for _, v := range all {
doItem(v)
}
}
} instead? And what is |
I prefer unnested code. func do(cond bool) error {
var all = iter.Empty[int]()
if cond {
var err error
all, err = findAll()
if err != nil {
return fmt.Errorf("failed to find all: %w", err)
}
}
for _, v := range all {
doItem(v)
}
return nil
} v.s. func do(cond bool) error {
if cond {
if all, err := findAll(); err != nil {
return fmt.Errorf("failed to find all: %w", err)
} else if all != nil {
for _, v := range all {
doItem(v)
}
}
}
return nil
}
I think it's less readable. var all = func(func(int) bool) {} // what's this!? v.s. var all = iter.Empty[int]() // I see, this is empty iterator. |
How about func do(cond bool) error {
if !cond {
return nil
}
all, err := findAll()
if err != nil {
return fmt.Errorf("failed to find all: %w", err)
}
if all == nil {
return nil
}
for _, v := range all {
doItem(v)
}
return nil
} instead? And again, what is I just can't see this kind of thing coming up very often. Maybe I'm wrong, but I feel like this should be added once it's proven to be an annoyance, rather than in advance as a counter to what seems likely to me to be a non-existent problem. |
Please consider the sutuation you can't early return by if !cond {
return nil
} because we need to do some after iteration for _, v := range all {
doItem(v)
}
doAfterIteration()
return nil I just want to say there are many codes which depends on iteration safety of nil slice/map. |
How about this case? func getIds() []int {
if condA {
return nil
}
somethingAfterA()
if condB {
return nil
}
somethingAfterB()
if condC {
return nil
}
somethingAfterC()
return getIdsImpl()
}
func do() {
for _, v := range getIds() {
println(v)
}
} When func getIds() iter.Seq[int] {
if condA {
return iter.Empty[int]()
}
somethingAfterA()
if condB {
return iter.Empty[int]()
}
somethingAfterB()
if condC {
return iter.Empty[int]()
}
somethingAfterC()
return getIdsImpl()
}
func do() {
for _, v := range getIds() {
println(v)
}
} |
That would be really useful. For now, it is possible to use Codepackage main
import (
"iter"
"slices"
"testing"
)
func getIter1[T any]() iter.Seq[T] {
return slices.Values[[]T](nil)
}
func getIter2[T any]() iter.Seq[T] {
return func(yield func(T) bool) {}
}
func BenchmarkIterNil(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
sum := 0
for num := range getIter1[int]() {
sum += num
}
}
}
func BenchmarkIterEmpty(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
sum := 0
for num := range getIter2[int]() {
sum += num
}
}
} Benchmarks
|
…eturn always the current state as the first element (#3961) Seems that some of the utility functions implemented here are still discussed by Go people: golang/go#66187 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Proposal Details
Add
Empty
function toiter
package.This function returns empty iterator.
Implementation
Usage
This function is useful to replace slice/map implementation to iter implementation.
Please see following code.
This function do something to all item when
cond
is true.#65629 was declined, so range over nil function panics.
I have to rewrite like following.
When
Empty
function exists, I can migrate code easily.The text was updated successfully, but these errors were encountered: