增加迭代器示例
This commit is contained in:
parent
cf84652c4d
commit
0ab01f3a8f
8
go.mod
8
go.mod
@ -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
22
go.sum
@ -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
52
iterator/set.go
Normal 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
48
iterator/set_test.go
Normal 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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user