返回介绍

05.9.3 使用 container/ring

发布于 2024-08-14 12:50:32 字数 5265 浏览 0 评论 0 收藏 0

使用 container/ring

这一节中将使用 conRing.go 中的 Go 语言代码阐述 container/ring 包的用法,下面分为四个部分介绍。注意,container/ringcontainer/listcontainer/heap 都简单多了,也就是说这个包中的函数比另外两个包中的要少一些。

conRing.go 中的第一个代码段如下:

package main

import (
    "container/ring"
    "fmt"
)

var size int = 10

size 变量存储了要创建的环的大小。

conRing.go 的第二部分包含如下 Go 代码:

func main() {
    myRing := ring.New(size + 1)
    fmt.Println("Empty ring:", *myRing)

    for i := 0; i < myRing.Len()-1; i++ {
        myRing.Value = i
        myRing = myRing.Next()
    }

    myRing.Value = 2

从上面可知,创建新的环需要使用 ring.New() 函数,它需要接受一个提供环的大小的参数。最后的 myRing.Value = 2 语句向环中加入了 2 这个值。不过前面的 for 循环中已经向环中加入了那个值。最后,环的零值指的是只有一个值为 nil 的元素的环。

conRing.go 的第三部分如下:

    sum := 0
    myRing.Do(func(x interface{}) {
        t := x.(int)
        sum = sum + t
    })
    fmt.Println("Sum:", sum)

ring.Do() 函数可以对环上的每个元素依次调用一个函数。然而 ring.Do() 没有定义对环进行修改的行为。x.(int) 语句称为类型断言。第 7 章“反射和接口”中将详细介绍类型断言。目前,你只用知道这表示 xint 类型的就行了。

conRing.go 的最后一部分程序如下:

    for i := 0; i < myRing.Len()+2; i++ {
        myRing = myRing.Next()
        fmt.Print(myRing.Value, " ")
    }
    fmt.Println()
}

使用环会遇到的唯一的问题就是你可以无限调用 ring.Next(),所以你需要找到停下来的办法。这种情况下就需要用到 ring.Len() 函数。就个人而言,我比较倾向于使用 ring.Do() 函数来迭代环上的所有元素,因为这样代码更简洁,但用 for 循环其实也不错!

执行 conRing.go 将会生成如下输出:

$ go run conRing.go
Empty ring: {0x42000a080 0xc42000a1a0 <nil>}
Sum: 47
0 1 2 3 4 5 6 7 8 9 2 0 1

输出的结果证明环上可以存在重复的值,也就是说你只能通过 ring.Len() 函数才能安全地获取到环的大小。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文