1. 匿名结构体
1
2
3
4
5
|
var config struct {//定义一个用于全局配置结构体
APIKey string
OAuthConfig oauth.Config
}
config.APIKey = "BADC0C0A"
|
1
2
3
4
5
6
7
8
|
data := struct {//匿名结构体的定义
Title string
Users []*User
}{//同时初始化
title,
users,
}
err := tmpl.Execute(w, data)
|
(比map[string]interface{}消耗更小和更安全)
1
2
3
4
5
6
7
8
9
10
|
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},
}
|
1
2
3
4
5
6
7
|
var hits struct {
sync.Mutex
n int
}
hits.Lock()
hits.n++//十对“n”的操作是安全的
hits.Unlock()
|
2. 嵌套结构体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
{"data": {"children": [
{"data": {
"title": "The Go homepage",
"url": "http://golang.org/"
}},
...
]}}
type Item struct {
Title string
URL string
}
type Response struct {
Data struct {
Children []struct {
Data Item
}
}
}
|
3. godoc命令,输出package的文档注释
输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
PACKAGE
package sync
import "sync"
TYPES
type Mutex struct {
// contains filtered or 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()
Lock locks m. If the lock is already in use, the calling goroutine
blocks until the mutex is available.
func (m *Mutex) Unlock()
Unlock unlocks m. It is a run-time error if m is not locked on entry to
Unlock.
A locked Mutex is not associated with a particular goroutine. It is
allowed for one goroutine to lock a Mutex and then arrange for another
goroutine to unlock it.
|
4. godoc -src 命令
1
|
% godoc -src sync Mutex
|
输出
1
2
3
4
5
6
7
|
// 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.
type Mutex struct {
state int32
sema uint32
}
|
未导出的元素也将显示!
5. 获取指定域名下的包
1
|
go get camlistore.org/pkg/netutil
|
go help remote
可查看更详细的信息.
6. 模拟一个文件系统
获取到的包里,代码访问了文件系统,但是测试时不希望真正访问磁盘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var fs fileSystem = osFS{}
type fileSystem interface {
Open(name string) (file, error)
Stat(name string) (os.FileInfo, error)
}
type file interface {
io.Closer
io.Reader
io.ReaderAt
io.Seeker
Stat() (os.FileInfo, error)
}
// osFS 实现接口filesystem,并访问本地磁盘.
type osFS struct{}
func (osFS) Open(name string) (file, error) { return os.Open(name) }
func (osFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) }
|
7. 方法表达式
1
2
3
4
|
type T struct {}
func (T) Foo(s string) { println(s) }
var fn func(T, string) = T.Foo//将方法赋值给一个方法变量
|
os/exec中的实际例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
func (c *Cmd) stdin() (f *os.File, err error)
func (c *Cmd) stdout() (f *os.File, err error)
func (c *Cmd) stderr() (f *os.File, err error)
type F func(*Cmd) (*os.File, error)
for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
fd, err := setupFd(c)
if err != nil {
c.closeDescriptors(c.closeAfterStart)
c.closeDescriptors(c.closeAfterWait)
return err
}
c.childFiles = append(c.childFiles, fd)
}
|
8. 使用统一个Channel发送和接收消息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package main
import "fmt"
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 }
}
|
9. 使用channel的close发送广播
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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
}
}
|
另外一个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
func worker(i int, ch chan Work, quit chan struct{}) {
var quitting bool
for {
select {
case w := <-ch:
if quitting {
w.Refuse(); fmt.Println("worker", i, "refused", w)
break
}
w.Do(); fmt.Println("worker", i, "processed", w)
case <-quit:
fmt.Println("worker", i, "quitting")
quitting = true
}
}
}
func main() {
ch, quit := make(chan Work), make(chan struct{})
go makeWork(ch)
for i := 0; i < 4; i++ { go worker(i, ch, quit) }
time.Sleep(5 * time.Second)
close(quit)
time.Sleep(2 * time.Second)
}
|
10. select中使用空channel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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
}
}
}
func main() {
ch, quit := make(chan Work), make(chan struct{})
go makeWork(ch)
for i := 0; i < 4; i++ { go worker(i, ch, quit) }
time.Sleep(5 * time.Second)
close(quit)
time.Sleep(2 * time.Second)
}
|