glist
带并发安全开关的双向列表。
使用场景:
默认情况下为非并发安全,也可以开启并发安全特性来使用到并发安全场景中。
使用方式:
import "github.com/gogf/gf/container/glist"
接口文档:
https://godoc.org/github.com/gogf/gf/container/glist
性能测试
https://github.com/gogf/gf/blob/master/container/glist/glist_z_bench_test.go
goos: darwin
goarch: amd64
pkg: github.com/gogf/gf/container/glist
Benchmark_PushBack-4 5000000 268 ns/op 56 B/op 2 allocs/op
Benchmark_PushFront-4 10000000 435 ns/op 56 B/op 2 allocs/op
Benchmark_Len-4 30000000 44.5 ns/op 0 B/op 0 allocs/op
Benchmark_PopFront-4 20000000 71.1 ns/op 0 B/op 0 allocs/op
Benchmark_PopBack-4 30000000 70.1 ns/op 0 B/op 0 allocs/op
PASS
使用示例
示例1,简单使用
package main
import (
"fmt"
"github.com/gogf/gf/container/glist"
)
func main() {
// Not concurrent-safe in default.
l := glist.New()
// Push
l.PushBack(1)
l.PushBack(2)
e := l.PushFront(0)
// Insert
l.InsertBefore(e, -1)
l.InsertAfter(e, "a")
fmt.Println(l)
// Pop
fmt.Println(l.PopFront())
fmt.Println(l.PopBack())
fmt.Println(l)
}
执行后,输出结果:
[-1,0,"a",1,2]
-1
2
[0,"a",1]
示例2,链表遍历
该示例中我们将通过读锁和写锁遍历一个并发安全的链表,分别通过RLockFunc
和LockFunc
实现。
package main
import (
"container/list"
"fmt"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/container/glist"
)
func main() {
// concurrent-safe list.
l := glist.NewFrom(garray.NewArrayRange(1, 10, 1).Slice(), true)
// iterate reading from head.
l.RLockFunc(func(list *list.List) {
length := list.Len()
if length > 0 {
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
fmt.Print(e.Value)
}
}
})
fmt.Println()
// iterate reading from tail.
l.RLockFunc(func(list *list.List) {
length := list.Len()
if length > 0 {
for i, e := 0, list.Back(); i < length; i, e = i+1, e.Prev() {
fmt.Print(e.Value)
}
}
})
fmt.Println()
// iterate reading from head using IteratorAsc.
l.IteratorAsc(func(e *glist.Element) bool {
fmt.Print(e.Value)
return true
})
fmt.Println()
// iterate reading from tail using IteratorDesc.
l.IteratorDesc(func(e *glist.Element) bool {
fmt.Print(e.Value)
return true
})
fmt.Println()
// iterate writing from head.
l.LockFunc(func(list *list.List) {
length := list.Len()
if length > 0 {
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
if e.Value == 6 {
e.Value = "M"
break
}
}
}
})
fmt.Println(l)
}
执行后,输出结果为:
12345678910
10987654321
12345678910
10987654321
[1,2,3,4,5,"M",7,8,9,10]
示例3,JSON序列化/反序列
glist
容器实现了标准库json
数据格式的序列化/反序列化接口。
Marshal
package main
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/container/glist"
"github.com/gogf/gf/frame/g"
)
func main() {
type Student struct {
Id int
Name string
Scores *glist.List
}
s := Student{
Id: 1,
Name: "john",
Scores: glist.NewFrom(g.Slice{100, 99, 98}),
}
b, _ := json.Marshal(s)
fmt.Println(string(b))
}
执行后,输出结果:
{"Id":1,"Name":"john","Scores":[100,99,98]}
Unmarshal
package main
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/container/glist"
)
func main() {
b := []byte(`{"Id":1,"Name":"john","Scores":[100,99,98]}`)
type Student struct {
Id int
Name string
Scores *glist.List
}
s := Student{}
json.Unmarshal(b, &s)
fmt.Println(s)
}
执行后,输出结果:
{1 john [100,99,98]}