一、介绍

ring是一个首尾相连的list,源码位于 src/container/ring/ring.go
其中每一个元素的定义如下:

// A Ring is an element of a circular list, or ring.
// Rings do not have a beginning or end; a pointer to any ring element
// serves as reference to the entire ring. Empty rings are represented
// as nil Ring pointers. The zero value for a Ring is a one-element
// ring with a nil Value.
//
type Ring struct {
    next, prev *Ring
    Value      interface{} // for use by client; untouched by this library
}

Ring结构中,只有一个Value存储值,以及指向prev以及next的指针地址。
通过New方法可以创建一个特定大小的ring,例如:

r := ring.New(5)

我们可以看下源码:

// New creates a ring of n elements.
func New(n int) *Ring {
    if n <= 0 {
        return nil
    }
    r := new(Ring)
    p := r
    for i := 1; i < n; i++ {
        p.next = &Ring{prev: p}
        p = p.next
    }
    p.next = r
    r.prev = p
    return r
}

1.1 ring.New(0) 是一个nil

我们使用 ring.New(0) 会发现是一个nil

func TestNew(t *testing.T) {
    r := ring.New(0)
    t.Log(r) //nil
    t.Log(r.Len()) //0
}

1.2 ring.New(1) 只有一个元素的环形链表

我们写一个测试方法

import (
    "container/ring"
    "testing"
)

func TestNew(t *testing.T) {
    r := ring.New(1)
    t.Log(r)
    t.Log(r.Next())
    t.Log(r.Prev())
    t.Log(r.Len())
}

输出:

&{0xc00000c0e0 0xc00000c0e0 <nil>}
&{0xc00000c0e0 0xc00000c0e0 <nil>}
&{0xc00000c0e0 0xc00000c0e0 <nil>}
1

我们发现地址都是r的地址,prev和next,都是存储的r
image.png

1.2 ring.New(n) n大于一个元素的环形链表

1.2.1 ring.New(2)

func TestNew(t *testing.T) {
    r := ring.New(2)
    t.Log(r)
    t.Log(r.Next())
    t.Log(r.Prev())
    t.Log(r.Len())
}

image.png

1.2.2 ring.New(4) 3个以及以上,就像圆形了。

import (
    "container/ring"
    "testing"
)

func TestNew(t *testing.T) {
    r1 := ring.New(4)
    t.Log(r1)                      //r1 地址 0xc00000c100
    t.Log(r1.Next())               //r2 地址 0xc00000c120
    t.Log(r1.Next().Next())        //r3 地址 0xc00000c140
    t.Log(r1.Next().Next().Next()) //r4 地址 0xc00000c0e0
    t.Log(r1.Len())                //4
}

image.png

谢谢您的观看,欢迎关注我的公众号。

image.png


海生
104 声望32 粉丝

与黑夜里,追求那一抹萤火。