使用golang的slice来模拟栈

  • slice(切片):底层数据结构是数组
  • stack(栈):一种先进后出的数据结构
普通版的模拟写入和读取的栈
package main

import "fmt"

//栈的特点是先进后出
//使用一个切片的全局变量来模拟栈
var stack []int

//向栈中添加数据
func push(value int) {
    stack = append(stack, value)
}

//从栈中获取数据
func pop() (int, bool) {
    ok := false
    value := 0
    if len(stack) > 0 {
        value = stack[len(stack)-1]
        stack = stack[:len(stack)-1]
        ok = true
        return value, ok
    } else {
        return value, ok
    }
}

func main() {
    //向栈中添加数据
    for i := 0; i < 10; i++ {
        push(i)
        fmt.Println(stack)
    }
    //从栈中获取数据
    for {
        v, ok := pop()
        if ok {
            fmt.Println(v)
        } else {
            break
        }
    }
}

 

使用goroutine来异步读取栈中数据或往栈中写入数据
package main

import (
    "fmt"
)

//栈的特点是先进后出
//使用一个切片的全局变量来模拟栈
var stack1 []int

//此通道用于通知主协程已经完成操作了
//但是此操作有可能不会输出全部数据
//因为添加数据和获取数据是异步的
//当获取数据的速度快于写入数据
//便不会输出全部数据
var e chan int = make(chan int)

//向栈中添加数据
func push1(value int) {
    stack1 = append(stack1, value)
    fmt.Println(stack1)
}

//从栈中获取数据
func pop1() {
    for {
        if len(stack1) > 0 {
            value := stack1[len(stack1)-1]
            stack1 = stack1[:len(stack1)-1]
            fmt.Println(value)
        } else {
            e <- 0
        }
    }
}

func main() {
    for i := 0; i < 10; i++ {
        go push1(i)
    }

    go pop1()

    <-e
}

 

输出:

[1]
[1 6 5 9 3 2 7 0 4]
[1 6 5 9 3 2 7 0 4 8]
[1 6 5]
[1 6]
[1 6 5 9 3 2 7 0]
[1 6 5 9]
[1 6 5 9 3 2]
[1 6 5 9 3 2 7]
8
4
0
7
2
3
9
5
6
1
[1 6 5 9 3]

使用goroutine异步读取或者写入的时一定要注意通道的写法,很容易造成死锁

posted @ 2018-11-03 22:57  timliudream  阅读(1981)  评论(0编辑  收藏  举报