一、Effective_go

1.1 formatting

  • formatting - 原文
  • 格式化,统一由go fmt实现,不再有不同的风格,大家统一适应,提高代码的可读性

1.2 Commentary-注释

  • Commentary - 原文
  • 注释(包是块-block注释、其他是由行注释),每个包是最小的组合单元,每个包功能集中处理的事。
  • 包的注释一般注释在同包名相同的文件顶部,由块-block注释,如果包功能简单,也可以采用行注释
  • 注释决定go doc生成文档的好坏
  • 对于统一申明可以分组备注,不用以声明的变量开始

1.3 Names

1.3.1 Package names

  • Package names - 原文
  • should be good:short, concise, evocative
  • should be lower case, single-word names,no need for underscores or mixedCaps
  • 先验碰撞?
  • ring.New()和ring.NewRing()谁更简洁,什么时候使用谁,与包什么关系?那么once.Do(setup)和once.DoOrWaitUntilDone(setup)呢?
  • 方法名并不能够让方法阐述清楚方法的作用与边界,还是需要靠注释和文档来阐述,否则就会发生似懂非懂的情景。

1.3.2 Getters

  • Getters - 原文
  • 通过暴露大些开头的方法来替代Getter方法,比如owner = obj.Owner()。
  • Setter也是一样,比如SetOwner

1.3.3 Interface names

  • Interface names - 原文
  • 惯例:接口后面加上-er来标识接口Reader, Writer, Formatter, CloseNotifier
  • 实现接口拥有相同的含义,则使用相同的名称和签名

1.3.4 MixedCaps

1.4 Semicolons

  • Semicolons - 原文
  • Go本身是使用分号来终止语法,但并不体现在源码中,使用lexer词法分析工具自动添加分号。
  • if, for, switch, or select控制语句,块的括号(parentheses)不能以下一行开始

1.5 Control structures

1.5.1 If

  • If - 原文
  • break, continue, goto, or return
  • 控制流中如果发生错误则return结束,if语句中不需要else语句

1.5.2 Redeclaration and reassignment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
1. var err error
2. if true {
3.     var f *os.File
4.     // f, err = os.Open("log.txt")
5.     f, err := os.Open("log.txt")
6.     fmt.Println(&err)
7.     // _, err := f.Stat()
8.     d, err := f.Stat()
9.     fmt.Println(&err)
10. }
11. fmt.Println(&err)
  • Redeclaration and reassignment - 原文
  • 方块中第5行err声明(短声明)的,第8行err只是给它重新分配了个新值
  • 方块中第5行声明短err是一个新的变量,与方块外第1行的err是两个不同的变量
  • 关于短声明:一定有一个新的变量被声明,当第4行不声明新变量,第7行也会声明一个新变量。

1.5.3 For

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Like a C for
for init; condition; post { }

// Like a C while
for condition { }

// Like a C for(;;)
for { }

for key, value := range oldMap {
    newMap[key] = value
}

for key := range m {
    if key.expired() {
        delete(m, key)
    }
}

for pos, char := range "日本\x80語" { // \x80 is an illegal UTF-8 encoding
    fmt.Printf("character %#U starts at byte position %d\n", char, pos)
    // character U+65E5 '日' starts at byte position 0
    // character U+672C '本' starts at byte position 3
    // character U+FFFD '�' starts at byte position 6
    // character U+8A9E '語' starts at byte position 7
}
  • For - 原文
  • for循环有类似C的for的用法,也可以用于类似while用法
  • for range可以与array, slice, string, or map, or reading from a channel联用
  • 如果只接受一个值,丢弃第二个值,返回的第一个可能是索引或key值
  • 如果只要第二个值,则可以使用空白标识符-来丢弃第一个值,关于空白标识符的各种用法后面会继续介绍到
  • 对于字符串string,分离出单个Unicode起始点
  • Go没有逗号运算符,++--表达式

1.5.4 Switch

  • Switch - 原文
  • The expressions need not be constants or even integers
  • case判断条件之间可以用逗号分割
  • 可以通过break loop(标签)来跳出循环到标签处,标签只能用在loop语句

1.5.5 Type switch

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
    fmt.Printf("unexpected type %T\n", t)     // %T prints whatever type t has
case bool:
    fmt.Printf("boolean %t\n", t)             // t has type bool
case int:
    fmt.Printf("integer %d\n", t)             // t has type int
case *bool:
    fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
    fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
  • Type switch - 原文
  • 断言判断动态接口变量类型
  • t在不同的情况下,可能有不同类型的新变量

1.6 Functions

1.6.1 Multiple return values

1.6.2 Named result parameters

1.6.3 Defer

二、The Go Programming Language Specification

brush one

三、tour of Go

brush one

四、How to Write Go Code

brush one

五、Go源码和包

Go Package Source Packages brush one

The Go Blog