golang基础-goroutine初识、chan存取、goroutine和chan相结合、关闭chan、range取、单元测试

来源:互联网 发布:中国象棋手机版软件 编辑:程序博客网 时间:2024/06/05 09:40

      • goroute初识
      • channel存取
      • 开启goroute实现chan之间的同步存取
      • channel关闭
      • range
        • 单元测试

goroute初识

package mainimport (    "fmt"    // "os"    "time")func test(){    var i int     for {        fmt.Println(i)        time.Sleep(time.Second)        i++    }}func main() {    go test()    for {        fmt.Println("running in main")        time.Sleep(time.Second)    }}

利用go 启动一个goroute

channel存取

先进先出
线程安全,多个goroutine同时访问,不需要加锁
channel是有类型的,一个整数的channel只能存放整数

package mainimport (    "fmt"    // "fmt")type Stu struct{    name string}func main() {    //int类型    var intChan chan int     intChan = make(chan int,10)    intChan <- 10    a := <- intChan    fmt.Println(a)    fmt.Println("--------/map类型---------")    //map类型    var mapChan chan map[string]string    mapChan = make(chan map[string]string,10)    m:= make(map[string]string,16)    m["stu01"] = "001"    m["stu02"] = "002"    m["stu03"] = "003"    mapChan <- m    b := <- mapChan    fmt.Println(b)    fmt.Println("--------结构体---------")    //结构体    var stuChan chan Stu    stuChan = make(chan Stu,10)    stu:= Stu{        name:"safly",    }    stuChan <- stu    tempStu := <- stuChan    fmt.Println(tempStu)    fmt.Println("--------结构体内存地址---------")    //结构体内存地址值    var stuChanId chan *Stu    stuChanId = make(chan *Stu,10)    stuId := &Stu{        name:"safly",    }    stuChanId <- stuId    tempStuId := <- stuChanId    fmt.Println(tempStuId)    fmt.Println(*(tempStuId))    fmt.Println("-----------接口---------")    //接口    var StuInterChain chan interface{}    StuInterChain = make(chan interface{},10)    stuInit:= Stu{        name:"safly",    }    //存    StuInterChain <- &stuInit    //取    mFetchStu:= <- StuInterChain    fmt.Println(mFetchStu)    //转    var mStuConvert *Stu    mStuConvert,ok := mFetchStu.(*Stu)    if !ok{        fmt.Println("cannot convert")        return    }    fmt.Println(mStuConvert)    fmt.Println(*(mStuConvert))}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go10--------/map类型---------map[stu03:003 stu01:001 stu02:002]--------结构体---------{safly}--------结构体内存地址---------&{safly}{safly}-----------接口---------&{safly}&{safly}{safly}PS E:\golang\go_pro\src\safly>

开启goroute,实现chan之间的同步存取

package mainimport (    "time"    "fmt")func main() {    intChan := make(chan int,5)    go write(intChan)    go read(intChan)    time.Sleep(10 *time.Second)}/*由于管道容量是5,开启go写入10个数据,再写入5个数据,会阻塞,然而read每秒会读取一个,然后在会写入一个数据*/func write(ch chan int){    for i:= 0;i<10;i++{        ch <- i        fmt.Println("put data:",i)    }}func read(ch chan int){    for{        var b int        b = <- ch        fmt.Println(b)        time.Sleep(time.Second)    }}

测试输出如下:

PS E:\golang\go_pro\src\safly> go run demo.goput data: 0put data: 1put data: 2put data: 3put data: 4put data: 501put data: 62put data: 73put data: 84put data: 956789PS E:\golang\go_pro\src\safly>

channel关闭

channel关闭后,就不能取出数据了

package mainimport "fmt"func main() {    var ch chan int    ch = make(chan int, 5)    for i := 0; i < 5; i++ {        ch <- i    }    close(ch)    for {        var b int        b, ok := <-ch        if ok == false {            fmt.Println("chan is close")            break        }        fmt.Println(b)    }}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go01234chan is closePS E:\golang\go_pro\src\safly>

如果将close(ch)注释掉,意思是不关闭管道,那么会出现dead lock死锁
因为存入管道5个数字,然后无限取数据,会出现死锁

range

package mainimport "fmt"func main() {    var ch chan int    ch = make(chan int, 10)    for i := 0; i < 10; i++ {        ch <- i    }    close(ch)    for v := range ch {        fmt.Println(v)    }}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go0123456789PS E:\golang\go_pro\src\safly>

同样如果将close(ch)注释掉,意思是不关闭管道,那么会出现dead lock死锁
因为存入管道10个数字,然后无限取数据,在取出来第10个数据,在次range管道,会dead lock

单元测试

  1. 文件名必须以_test.go结尾
  2. 使用go test执行单元测试

这里写图片描述

calc.go

package mainfunc add(a, b int) int {    return a + b}func sub(a, b int) int {    return a - b}

calc_test.go

package mainimport (    "testing")func TestAdd(t *testing.T) {    r := add(2, 4)    if r != 6 {        t.Fatalf("add(2, 4) error, expect:%d, actual:%d", 6, r)    }    t.Logf("test add succ")}

来执行test测试如下:

版权所有 (C) 2016 Microsoft Corporation。保留所有权利。PS E:\golang\go_pro> cd srcPS E:\golang\go_pro\src> cd saflyPS E:\golang\go_pro\src\safly> cd testPS E:\golang\go_pro\src\safly\test> go testPASSok      safly/test      0.053s
原创粉丝点击