Skip to content

Commit

Permalink
list: Append 方法改造为不定参数形式 #36 (#58)
Browse files Browse the repository at this point in the history
* list: Append 方法改造为不定参数形式 #36

Signed-off-by: longyue0521 <longyueli0521@gmail.com>

* 去除多余空格

Signed-off-by: longyue0521 <longyueli0521@gmail.com>

* 修改CHANGELOG

Signed-off-by: longyue0521 <longyueli0521@gmail.com>

Signed-off-by: longyue0521 <longyueli0521@gmail.com>
  • Loading branch information
longyue0521 authored Aug 28, 2022
1 parent cf99797 commit 5b38f6f
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
- [Add() 和 NewLinkedListOf()](https://github.com/gotomicro/ekit/pull/26)
- [Get](https://github.com/gotomicro/ekit/pull/31)
- [Append](https://github.com/gotomicro/ekit/pull/34)
- [Append 方法改造为不定参数形式](https://github.com/gotomicro/ekit/pull/58)
- [Delete](https://github.com/gotomicro/ekit/pull/38)
- [Len,Cap,NewLinkedList](https://github.com/gotomicro/ekit/pull/51)
- [Range](https://github.com/gotomicro/ekit/pull/46)
- [pool: 修复 Pool TestPool 测试不稳定的问题](https://github.com/gotomicro/ekit/pull/40)
- [ekit:引入 golangci-lint 和 goimports](https://github.com/gotomicro/ekit/pull/54)

8 changes: 6 additions & 2 deletions list/array_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

package list

var (
_ List[any] = &ArrayList[any]{}
)

// ArrayList 基于切片的简单封装
type ArrayList[T any] struct {
vals []T
Expand All @@ -40,8 +44,8 @@ func (a *ArrayList[T]) Get(index int) (t T, e error) {
}

// Append 往ArrayList里追加数据
func (a *ArrayList[T]) Append(t T) error {
a.vals = append(a.vals, t)
func (a *ArrayList[T]) Append(ts ...T) error {
a.vals = append(a.vals, ts...)
return nil
}

Expand Down
60 changes: 51 additions & 9 deletions list/array_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,31 +132,73 @@ func TestArrayList_Append(t *testing.T) {
testCases := []struct {
name string
list *ArrayList[int]
newVal int
newVal []int
wantSlice []int
}{
{
name: "append 234",
name: "append non-empty values to non-empty list",
list: NewArrayListOf[int]([]int{123}),
newVal: 234,
wantSlice: []int{123, 234},
newVal: []int{234, 456},
wantSlice: []int{123, 234, 456},
},
{
name: "nil append 123",
list: NewArrayListOf[int](nil),
newVal: 123,
name: "append empty values to non-empty list",
list: NewArrayListOf[int]([]int{123}),
newVal: []int{},
wantSlice: []int{123},
},
{
name: "append nil to non-empty list",
list: NewArrayListOf[int]([]int{123}),
newVal: nil,
wantSlice: []int{123},
},
{
name: "append non-empty values to empty list",
list: NewArrayListOf[int]([]int{}),
newVal: []int{234, 456},
wantSlice: []int{234, 456},
},
{
name: "append empty values to empty list",
list: NewArrayListOf[int]([]int{}),
newVal: []int{},
wantSlice: []int{},
},
{
name: "append nil to empty list",
list: NewArrayListOf[int]([]int{}),
newVal: nil,
wantSlice: []int{},
},
{
name: "append non-empty values to nil list",
list: NewArrayListOf[int](nil),
newVal: []int{234, 456},
wantSlice: []int{234, 456},
},
{
name: "append empty values to nil list",
list: NewArrayListOf[int](nil),
newVal: []int{},
wantSlice: []int{},
},
{
name: "append nil to nil list",
list: NewArrayListOf[int](nil),
newVal: nil,
wantSlice: []int{},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.list.Append(tc.newVal)
err := tc.list.Append(tc.newVal...)
if err != nil {
return
}

assert.Equal(t, tc.wantSlice, tc.list.vals)
assert.Equal(t, tc.wantSlice, tc.list.AsSlice())
})
}
}
Expand Down
8 changes: 6 additions & 2 deletions list/concurrent_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ package list

import "sync"

var (
_ List[any] = &ConcurrentList[any]{}
)

// ConcurrentList 用读写锁封装了对 List 的操作
// 达到线程安全的目标
type ConcurrentList[T any] struct {
Expand All @@ -29,10 +33,10 @@ func (c *ConcurrentList[T]) Get(index int) (T, error) {
return c.List.Get(index)
}

func (c *ConcurrentList[T]) Append(t T) error {
func (c *ConcurrentList[T]) Append(ts ...T) error {
c.lock.Lock()
defer c.lock.Unlock()
return c.List.Append(t)
return c.List.Append(ts...)
}

func (c *ConcurrentList[T]) Add(index int, t T) error {
Expand Down
58 changes: 50 additions & 8 deletions list/concurrent_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,26 +110,68 @@ func TestConcurrentList_Append(t *testing.T) {
testCases := []struct {
name string
list *ConcurrentList[int]
newVal int
newVal []int
wantSlice []int
}{
{
name: "append 234",
name: "append non-empty values to non-empty list",
list: newConcurrentListOfSlice[int]([]int{123}),
newVal: 234,
wantSlice: []int{123, 234},
newVal: []int{234, 456},
wantSlice: []int{123, 234, 456},
},
{
name: "nil append 123",
list: newConcurrentListOfSlice[int](nil),
newVal: 123,
name: "append empty values to non-empty list",
list: newConcurrentListOfSlice[int]([]int{123}),
newVal: []int{},
wantSlice: []int{123},
},
{
name: "append nil to non-empty list",
list: newConcurrentListOfSlice[int]([]int{123}),
newVal: nil,
wantSlice: []int{123},
},
{
name: "append non-empty values to empty list",
list: newConcurrentListOfSlice[int]([]int{}),
newVal: []int{234, 456},
wantSlice: []int{234, 456},
},
{
name: "append empty values to empty list",
list: newConcurrentListOfSlice[int]([]int{}),
newVal: []int{},
wantSlice: []int{},
},
{
name: "append nil to empty list",
list: newConcurrentListOfSlice[int]([]int{}),
newVal: nil,
wantSlice: []int{},
},
{
name: "append non-empty values to nil list",
list: newConcurrentListOfSlice[int](nil),
newVal: []int{234, 456},
wantSlice: []int{234, 456},
},
{
name: "append empty values to nil list",
list: newConcurrentListOfSlice[int](nil),
newVal: []int{},
wantSlice: []int{},
},
{
name: "append nil to nil list",
list: newConcurrentListOfSlice[int](nil),
newVal: nil,
wantSlice: []int{},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.list.Append(tc.newVal)
err := tc.list.Append(tc.newVal...)
if err != nil {
return
}
Expand Down
26 changes: 16 additions & 10 deletions list/linked_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

package list

var (
_ List[any] = &LinkedList[any]{}
)

// LinkedList 双向链表
type LinkedList[T any] struct {
head *node[T]
Expand Down Expand Up @@ -52,17 +56,19 @@ func (l *LinkedList[T]) Get(index int) (T, error) {
}

// Append 往链表最后添加元素
func (l *LinkedList[T]) Append(t T) error {
newLastNode := &node[T]{val: t}
if l.length == 0 {
l.head = newLastNode
l.tail = newLastNode
} else {
l.tail.next = newLastNode
newLastNode.prev = l.tail
l.tail = newLastNode
func (l *LinkedList[T]) Append(ts ...T) error {
for _, t := range ts {
newLastNode := &node[T]{val: t}
if l.length == 0 {
l.head = newLastNode
l.tail = newLastNode
} else {
l.tail.next = newLastNode
newLastNode.prev = l.tail
l.tail = newLastNode
}
l.length += 1
}
l.length += 1
return nil
}

Expand Down
65 changes: 49 additions & 16 deletions list/linked_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,38 +186,71 @@ func TestLinkedList_Append(t *testing.T) {
name string
list *LinkedList[int]
index int
newVal int
newVal []int
wantLinkedList *LinkedList[int]
wantErr error
}{
{
name: "append val",
list: NewLinkedListOf[int]([]int{1, 2, 3}),
newVal: 100,
wantLinkedList: NewLinkedListOf[int]([]int{1, 2, 3, 100}),
name: "append non-empty values to non-empty list",
list: NewLinkedListOf[int]([]int{123}),
newVal: []int{234, 456},
wantLinkedList: NewLinkedListOf[int]([]int{123, 234, 456}),
},
{
name: "append val in list length of 1",
list: NewLinkedListOf[int]([]int{1}),
newVal: 100,
wantLinkedList: NewLinkedListOf[int]([]int{1, 100}),
name: "append empty values to non-empty list",
list: NewLinkedListOf[int]([]int{123}),
newVal: []int{},
wantLinkedList: NewLinkedListOf[int]([]int{123}),
},
{
name: "append nil to non-empty list",
list: NewLinkedListOf[int]([]int{123}),
newVal: nil,
wantLinkedList: NewLinkedListOf[int]([]int{123}),
},
{
name: "append val to nil list",
name: "append non-empty values to empty list",
list: NewLinkedListOf[int]([]int{}),
newVal: 100,
wantLinkedList: NewLinkedListOf[int]([]int{100}),
newVal: []int{234, 456},
wantLinkedList: NewLinkedListOf[int]([]int{234, 456}),
},
{
name: "append empty values to empty list",
list: NewLinkedListOf[int]([]int{}),
newVal: []int{},
wantLinkedList: NewLinkedListOf[int]([]int{}),
},
{
name: "append nil to empty list",
list: NewLinkedListOf[int]([]int{}),
newVal: nil,
wantLinkedList: NewLinkedListOf[int]([]int{}),
},
{
name: "append non-empty values to nil list",
list: NewLinkedListOf[int](nil),
newVal: []int{234, 456},
wantLinkedList: NewLinkedListOf[int]([]int{234, 456}),
},
{
name: "append empty values to nil list",
list: NewLinkedListOf[int](nil),
newVal: []int{},
wantLinkedList: NewLinkedListOf[int]([]int{}),
},
{
name: "append nil to nil list",
list: NewLinkedListOf[int](nil),
newVal: nil,
wantLinkedList: NewLinkedListOf[int]([]int{}),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.list.Append(tc.newVal)
err := tc.list.Append(tc.newVal...)
assert.Equal(t, tc.wantErr, err)
// 因为返回了 error,所以我们不用继续往下比较了
if err != nil {
return
}
assert.True(t, linkedListEqual(tc.list, tc.wantLinkedList))
})
}
Expand Down
2 changes: 1 addition & 1 deletion list/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type List[T any] interface {
// 在下标超出范围的情况下,返回错误
Get(index int) (T, error)
// Append 在末尾追加元素
Append(t T) error
Append(ts ...T) error
// Add 在特定下标处增加一个新元素
// 如果下标超出范围,应该返回错误
Add(index int, t T) error
Expand Down

0 comments on commit 5b38f6f

Please sign in to comment.