本文主要是介绍golang基础-goroutine初识、chan存取、goroutine和chan相结合、关闭chan、range取、单元测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
-
-
- 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 <- 10a := <- intChanfmt.Println(a)fmt.Println("--------/map类型---------")//map类型var mapChan chan map[string]stringmapChan = make(chan map[string]string,10)m:= make(map[string]string,16)m["stu01"] = "001"m["stu02"] = "002"m["stu03"] = "003"mapChan <- mb := <- mapChanfmt.Println(b)fmt.Println("--------结构体---------")//结构体var stuChan chan StustuChan = make(chan Stu,10)stu:= Stu{name:"safly",}stuChan <- stutempStu := <- stuChanfmt.Println(tempStu)fmt.Println("--------结构体内存地址---------")//结构体内存地址值var stuChanId chan *StustuChanId = make(chan *Stu,10)stuId := &Stu{name:"safly",}stuChanId <- stuIdtempStuId := <- stuChanIdfmt.Println(tempStuId)fmt.Println(*(tempStuId))fmt.Println("-----------接口---------")//接口var StuInterChain chan interface{}StuInterChain = make(chan interface{},10)stuInit:= Stu{name:"safly",}//存StuInterChain <- &stuInit//取mFetchStu:= <- StuInterChainfmt.Println(mFetchStu)//转var mStuConvert *StumStuConvert,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.go
10
--------/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 <- ifmt.Println("put data:",i)}
}func read(ch chan int){for{var b intb = <- chfmt.Println(b)time.Sleep(time.Second)}
}
测试输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
put data: 0
put data: 1
put data: 2
put data: 3
put data: 4
put data: 5
0
1
put data: 6
2
put data: 7
3
put data: 8
4
put data: 9
5
6
7
8
9
PS E:\golang\go_pro\src\safly>
channel关闭
channel关闭后,就不能取出数据了
package mainimport "fmt"func main() {var ch chan intch = make(chan int, 5)for i := 0; i < 5; i++ {ch <- i}close(ch)for {var b intb, ok := <-chif ok == false {fmt.Println("chan is close")break}fmt.Println(b)}
}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
0
1
2
3
4
chan is close
PS E:\golang\go_pro\src\safly>
如果将close(ch)注释掉,意思是不关闭管道,那么会出现dead lock死锁
因为存入管道5个数字,然后无限取数据,会出现死锁
range
package mainimport "fmt"func main() {var ch chan intch = 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.go
0
1
2
3
4
5
6
7
8
9
PS E:\golang\go_pro\src\safly>
同样如果将close(ch)注释掉,意思是不关闭管道,那么会出现dead lock死锁
因为存入管道10个数字,然后无限取数据,在取出来第10个数据,在次range管道,会dead lock
单元测试
- 文件名必须以_test.go结尾
- 使用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 src
PS E:\golang\go_pro\src> cd safly
PS E:\golang\go_pro\src\safly> cd test
PS E:\golang\go_pro\src\safly\test> go test
PASS
ok safly/test 0.053s
这篇关于golang基础-goroutine初识、chan存取、goroutine和chan相结合、关闭chan、range取、单元测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!