generic bag

This commit is contained in:
Gregory 2021-12-15 23:40:14 +02:00
parent cd3878d698
commit 4c42af490b
2 changed files with 16 additions and 21 deletions

View file

@ -1,11 +1,6 @@
package bag package bag
// "Generic" item. type Bag[Item any] interface {
// When type parameters will land this type became
// type Item[T any] T
type Item interface{}
type Bag interface {
Add(Item) Add(Item)
Size() int Size() int
IsEmpty() bool IsEmpty() bool
@ -14,37 +9,37 @@ type Bag interface {
// We use linked list as internal data structure // We use linked list as internal data structure
// to get O(1) speed for Add operation // to get O(1) speed for Add operation
type node struct { type node[Item any] struct {
item Item item Item
next *node next *node[Item]
} }
type bag struct { type bag[OfType any] struct {
size int size int
head *node head *node[OfType]
} }
func NewBag() Bag { func NewBag[OfType any]() Bag[OfType] {
return &bag{} return &bag[OfType]{}
} }
func (b *bag) Add(item Item) { func (b *bag[OfType]) Add(item OfType) {
next := b.head next := b.head
b.head = &node{item, next} b.head = &node[OfType]{item, next}
b.size++ b.size++
} }
func (b *bag) Size() int { func (b *bag[_]) Size() int {
return b.size return b.size
} }
func (b *bag) IsEmpty() bool { func (b *bag[_]) IsEmpty() bool {
return b.size == 0 return b.size == 0
} }
// As for now Go doesn't have iterators. // As for now Go doesn't have iterators.
// But we can simulate them with ForEach method // But we can simulate them with ForEach method
func (b *bag) ForEach(f func(Item)) { func (b *bag[OfType]) ForEach(f func(OfType)) {
for current := b.head; current != nil; current = current.next { for current := b.head; current != nil; current = current.next {
f(current.item) f(current.item)
} }

View file

@ -6,14 +6,14 @@ import (
) )
func TestSimple(t *testing.T) { func TestSimple(t *testing.T) {
bag := NewBag() bag := NewBag[int]()
sum := 0 sum := 0
bag.Add(1) bag.Add(1)
bag.Add(2) bag.Add(2)
bag.Add(3) bag.Add(3)
bag.ForEach(func(i Item) { sum += i.(int) }) bag.ForEach(func(i int) { sum += i })
if sum != 6 { if sum != 6 {
log.Fatal("wrong items in bag") log.Fatal("wrong items in bag")
@ -21,14 +21,14 @@ func TestSimple(t *testing.T) {
} }
func TestEmpty(t *testing.T) { func TestEmpty(t *testing.T) {
bag := NewBag() bag := NewBag[int]()
sum := 0 sum := 0
if bag.Size() != 0 || !bag.IsEmpty() { if bag.Size() != 0 || !bag.IsEmpty() {
log.Fatal("bag should be empty") log.Fatal("bag should be empty")
} }
bag.ForEach(func(i Item) { sum += i.(int) }) bag.ForEach(func(i int) { sum += i })
if sum != 0 { if sum != 0 {
log.Fatal("wrong items in bag") log.Fatal("wrong items in bag")