匿名結(jié)構(gòu)體
最常見的匿名用法上沐,不用單獨定義一個結(jié)構(gòu)體類型
var config struct {
APIKey string
OAuthConfig oauth.Config
}
config.APIKey = "BADC0C0A"
匿名結(jié)構(gòu)體定義時并初始化
data := struct {
Title string
Users []*User
}{
title,
users,
}
err := tmpl.Execute(w, data)
匿名結(jié)構(gòu)體slice定義并初始化
var indexRuneTests = []struct {
s string
rune rune
out int
}{
{"a A x", 'A', 2},
{"some_text=some_value", '=', 9},
{"?a", 'a', 3},
{"a??b", '?', 4},
}
嵌套互斥鎖
var hits struct {
sync.Mutex
n int
}
hits.Lock()
hits.n++
hits.Unlock()
嵌套結(jié)構(gòu)體
type Item struct {
Title string
URL string
}
type Response struct {
Data struct {
Children []struct {
Data Item
}
}
}
命令行 go doc
在命令行中,可以通過go doc 查看包相關(guān)接口信息
wdy@wdy:~/learn/program-learn/golang$ go doc sync
package sync // import "sync"
Package sync provides basic synchronization primitives such as mutual
exclusion locks. Other than the Once and WaitGroup types, most are intended
for use by low-level library routines. Higher-level synchronization is
better done via channels and communication.
Values containing the types defined in this package should not be copied.
func NewCond(l Locker) *Cond
type Cond struct { ... }
type Locker interface { ... }
type Mutex struct { ... }
type Once struct { ... }
type Pool struct { ... }
type RWMutex struct { ... }
type WaitGroup struct { ... }
wdy@wdy:~/learn/program-learn/golang$ go doc sync Mutex
type Mutex struct {
// Has unexported fields.
}
A Mutex is a mutual exclusion lock. Mutexes can be created as part of other
structures; the zero value for a Mutex is an unlocked mutex.
func (m *Mutex) Lock()
func (m *Mutex) Unlock()
wdy@wdy:~/learn/program-learn/golang$ go doc sync.mutex.lock
func (m *Mutex) Lock()
Lock locks m. If the lock is already in use, the calling goroutine blocks
until the mutex is available.
另外還有一個厲害的工具 ,執(zhí)行下面命令
godoc -http :6061
會打開一個網(wǎng)頁如下:
2017-07-11 19:16:11屏幕截圖.png
可以方便的查詢各個package的相關(guān)知識。
在同一個channel上進行讀寫操作
battle是一個阻塞channel,當(dāng)多個goroutine執(zhí)行warrior的時候,最先執(zhí)行到select的goroutine進入到
case battle <- name:
此時其他goroutine會阻塞在select上,name進入battle的瞬間,阻塞等待的goroutine的其中一個會進入到
case opponent := <-battle:
battle數(shù)據(jù)被讀取后,阻塞等待的剩余的goroutine的其中一個會進入到
case battle <- name:
按照如上流程反復(fù)直到所有g(shù)oroutine執(zhí)行完畢理朋。
var battle = make(chan string)
func warrior(name string, done chan struct{}) {
select {
case opponent := <-battle:
fmt.Printf("%s beat %s\n", name, opponent)
case battle <- name:
// I lost :-(
}
done <- struct{}{}
}
func main() {
done := make(chan struct{})
langs := []string{"Go", "C", "C++", "Java", "Perl", "Python"}
for _, l := range langs {
go warrior(l, done)
}
for _ = range langs {
<-done
}
}
可以看到每次結(jié)果都是不一樣的
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go
Go beat Python
C++ beat C
Java beat Perl
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go
Perl beat Java
Python beat Go
C beat C++
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go
C++ beat C
Java beat Perl
Python beat Go
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go
Go beat Python
Perl beat Java
C beat C++
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go
Python beat Go
C beat C++
Java beat Perl
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go
Go beat Python
Perl beat Java
C beat C++
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go
Go beat Python
C beat C++
Java beat Perl
利用close來向其他goroutine廣播
func waiter(i int, block, done chan struct{}) {
time.Sleep(time.Duration(rand.Intn(3000)) * time.Millisecond)
fmt.Println(i, "waiting...")
<-block
fmt.Println(i, "done!")
done <- struct{}{}
}
func main() {
block, done := make(chan struct{}), make(chan struct{})
for i := 0; i < 4; i++ {
go waiter(i, block, done)
}
time.Sleep(5 * time.Second)
close(block)
for i := 0; i < 4; i++ {
<-done
}
}
結(jié)果
2 waiting...
1 waiting...
3 waiting...
0 waiting...
0 done!
3 done!
2 done!
1 done!
利用nil通道的特性
goroutine對于值為nil的channel進行接受或發(fā)送操作時,會永久block
type Work struct {
Job string
}
func (w Work) Do() {
fmt.Println("do", w.Job)
}
func (w Work) Refuse() {
fmt.Println(w.Job + "stopped")
}
func makeWork(ch chan Work) {
for {
time.Sleep(500 * time.Millisecond)
ch <- Work{Job: "job"}
}
}
func worker(i int, ch chan Work, quit chan struct{}) {
for {
select {
case w := <-ch:
if quit == nil {
w.Refuse()
fmt.Println("worker", i, "refused", w)
break
}
w.Do()
fmt.Println("worker", i, "processed", w)
case <-quit:
fmt.Println("worker", i, "quitting")
quit = nil
}
}
}
結(jié)果
do job
worker 0 processed {job}
do job
worker 1 processed {job}
do job
worker 2 processed {job}
do job
worker 3 processed {job}
do job
worker 0 processed {job}
do job
worker 1 processed {job}
do job
worker 2 processed {job}
do job
worker 3 processed {job}
do job
worker 0 processed {job}
worker 0 quitting
worker 1 quitting
worker 2 quitting
worker 3 quitting
jobstopped
worker 0 refused {job}
jobstopped
worker 1 refused {job}
jobstopped
worker 2 refused {job}
jobstopped
worker 3 refused {job}
后記
之前一直在CSDN上寫文章绿聘,后面會逐步轉(zhuǎn)換到簡書上嗽上,還請大家多多支持。