This is a creation in Article, where the information may have evolved or changed.
English original
anonymous struct
The most common anonymous usage, without having to define a struct type individually
var config struct { APIKey string OAuthConfig oauth.Config } config.APIKey = "BADC0C0A"
Anonymous struct is defined and initialized
data := struct { Title string Users []*User }{ title, users, } err := tmpl.Execute(w, data)
anonymous struct slice definition and initialization
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}, }
Nesting Mutual exclusion locks
var hits struct { sync.Mutex n int } hits.Lock() hits.n++ hits.Unlock()
Nested structure body
type Item struct { Title string URL string } type Response struct { Data struct { Children []struct { Data Item } } }
Command line Go doc
On the command line, you can view package-related interface information via Go doc
wdy@wdy:~/learn/program-learn/golang$ go doc syncpackage sync // import "sync"Package sync provides basic synchronization primitives such as mutualexclusion locks. Other than the Once and WaitGroup types, most are intendedfor use by low-level library routines. Higher-level synchronization isbetter done via channels and communication.Values containing the types defined in this package should not be copied.func NewCond(l Locker) *Condtype 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 Mutextype 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.lockfunc (m *Mutex) Lock() Lock locks m. If the lock is already in use, the calling goroutine blocks until the mutex is available.
Read and write operations on the same channel
Battle is a blocking channel, and when multiple goroutine execute warrior, the goroutine that first executes to select enters
case battle <- name:
At this point the other goroutine will block on the Select, name enters Battle moment, one of the blocking waiting goroutine will go into
case opponent := <-battle:
After the battle data is read, one of the remaining goroutine that blocks the wait will go into
case battle <- name:
Follow the process as above until all goroutine are executed.
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 }}
You can see that the results are different every time.
wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.goGo beat PythonC++ beat CJava beat Perlwdy@wdy:~/learn/program-learn/golang$ go run learnchannel.goPerl beat JavaPython beat GoC beat C++wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.goC++ beat CJava beat PerlPython beat Gowdy@wdy:~/learn/program-learn/golang$ go run learnchannel.goGo beat PythonPerl beat JavaC beat C++wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.goPython beat GoC beat C++Java beat Perlwdy@wdy:~/learn/program-learn/golang$ go run learnchannel.goGo beat PythonPerl beat JavaC beat C++wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.goGo beat PythonC beat C++Java beat Perl
Use close to broadcast to other 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 }}
Results
2 waiting...1 waiting...3 waiting...0 waiting...0 done!3 done!2 done!1 done!
Using the features of the nil channel
Goroutine permanent block for the accept or send operation of a channel with a value of nil
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 } }}
Results
do jobworker 0 processed {job}do jobworker 1 processed {job}do jobworker 2 processed {job}do jobworker 3 processed {job}do jobworker 0 processed {job}do jobworker 1 processed {job}do jobworker 2 processed {job}do jobworker 3 processed {job}do jobworker 0 processed {job}worker 0 quittingworker 1 quittingworker 2 quittingworker 3 quittingjobstoppedworker 0 refused {job}jobstoppedworker 1 refused {job}jobstoppedworker 2 refused {job}jobstoppedworker 3 refused {job}
Postscript
has been in the csdn to write articles, the latter will be gradually converted to the book, but also ask you to support a lot.