增加迭代器示例

This commit is contained in:
fantasticbin 2024-11-12 14:52:48 +08:00
parent cf84652c4d
commit 0ab01f3a8f
4 changed files with 124 additions and 6 deletions

8
go.mod
View File

@ -1,17 +1,17 @@
module go-study
go 1.20
go 1.23
require (
github.com/marusama/cyclicbarrier v1.1.0
github.com/stretchr/testify v1.9.0
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
golang.org/x/sync v0.5.0
go.uber.org/mock v0.5.0
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f
golang.org/x/sync v0.9.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/mock v0.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

22
go.sum
View File

@ -1,8 +1,26 @@
github.com/brildum/testify v0.0.0-20151105045740-d05693e2e501 h1:ZWEmkmb/iJoRKLR0YuRP9wnEeF54NT3iUiGNTm/VQrs=
github.com/brildum/testify v0.0.0-20151105045740-d05693e2e501/go.mod h1:Zpjn5ClomJALLjz5sjBsNW79y3MarfpDcZaSJqbsIwk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/marusama/cyclicbarrier v1.1.0 h1:ol/AG+sjvh5yz832avbNjaowoerBuD3AgozxL+aD9u0=
github.com/marusama/cyclicbarrier v1.1.0/go.mod h1:5u93l83cy51YXdz6eKq6kO9+9mGAooB6DHMAxcSuWwQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

52
iterator/set.go Normal file
View File

@ -0,0 +1,52 @@
package iterator
import (
"iter"
)
type Set[T comparable] struct {
ordered []T // 用于保持顺序
m map[T]struct{}
}
func NewSet[T comparable]() *Set[T] {
return &Set[T]{make([]T, 0), make(map[T]struct{})}
}
func (s *Set[T]) Add(e T) {
if !s.Contains(e) {
s.ordered = append(s.ordered, e)
}
s.m[e] = struct{}{}
}
func (s *Set[T]) Remove(e T) {
for k, v := range s.ordered {
if v == e {
s.ordered = append(s.ordered[:k], s.ordered[k+1:]...)
break
}
}
delete(s.m, e)
}
func (s *Set[T]) Contains(e T) bool {
_, ok := s.m[e]
return ok
}
func (s *Set[T]) Len() int {
return len(s.m)
}
func (s *Set[T]) All() iter.Seq[T] {
return func(yield func(T) bool) {
// 迭代有序切片
for _, v := range s.ordered {
if !yield(v) {
return
}
}
}
}

48
iterator/set_test.go Normal file
View File

@ -0,0 +1,48 @@
package iterator
import (
"github.com/stretchr/testify/assert"
"iter"
"slices"
"testing"
)
func TestSet(t *testing.T) {
s := NewSet[string]()
list := []string{
"fantasticbin",
"phper",
"gopher",
"javaer",
}
var pull, push []string
expected := list[:3]
for v := range slices.Values(list) {
s.Add(v)
}
// 只推
for v := range s.All() {
if v == "javaer" {
break
}
push = append(push, v)
}
// 既推又拉
next, stop := iter.Pull(s.All())
for {
v, ok := next()
if !ok {
break
}
pull = append(pull, v)
if v == "gopher" {
stop()
}
}
assert.Equal(t, expected, push)
assert.Equal(t, expected, pull)
}