问题
使用切片实现栈,要求线程安全。
思路
栈主要特征就是数据先进后出,操作主要有push/pop/top/isempty,使用切片保存数据,为了线程安全,增加读写锁。
实现
直接上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| type SafeStack struct { data []interface{} sync.RWMutex }
func (s *SafeStack) initSilce() { if s.data == nil { s.data = make([]interface{}, 0) } }
func (s *SafeStack) Push(v interface{}) { s.Lock() defer s.Unlock() s.initSilce() s.data = append(s.data, v) }
func (s *SafeStack) Pop() (interface{}, error) { s.Lock() defer s.Unlock() s.initSilce() lenght := len(s.data) if lenght == 0 { return nil, errors.New("empty") } result := s.data[lenght-1] s.data = s.data[:lenght-1] return result, nil }
func (s *SafeStack) Top() (interface{}, error) { s.RLock() defer s.RUnlock() if s.data == nil || len(s.data) == 0 { return nil, errors.New("empty") } return s.data[len(s.data)-1], nil }
func (s *SafeStack) IsEmpty() bool { s.RLock() defer s.RUnlock() return s.data == nil || len(s.data) == 0 }
|
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| func main() { s := &SafeStack{}
fmt.Println(s.IsEmpty()) _, err1 := s.Top() if err1 != nil { fmt.Println(err1) } _, err2 := s.Pop() if err2 != nil { fmt.Println(err2) } for i := 0; i < 10; i++ { s.Push(i) } fmt.Println(s.IsEmpty()) v3, err3 := s.Top() if err3 != nil { fmt.Println(err3) } fmt.Println(v3) v4, err4 := s.Pop() if err4 != nil { fmt.Println(err4) } fmt.Println(v4) for { v5, err5 := s.Pop() if err5 != nil { fmt.Println(err5) break } fmt.Println(v5) } }
|
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| true empty empty false 9 9 8 7 6 5 4 3 2 1 0 empty
|