《GO语言圣经》读书笔记 第一章 入门

  1. 简洁的设计需要在工作开始的时候舍弃不必要的想法,并在软件的生命周期内严格区别好的改变和坏的改变; 一个好的改变可以在不破坏原有完整概念的前提下保持自适应,正如Fred *s所说的“概念完整性”。而一个坏的改变则不能达到这个效果,他们仅仅是通过肤浅的和简单的妥协来破坏原有设计的一致性。只有通过简洁的设计,才能让一个系统保持稳定、安全和持续的优化。

  2. Go语言的面向对象机制跟一般语言不同,它没有类层次结构,甚至可以说没有类。
    仅仅通过组合(而不是继承)简单的对象来构建复杂的对象。方法不仅可以定义在结构体上,而且可以定义在任何用户自定义的类型上。并且,具体类型和抽象类型(接口)之间的关系是隐式的。所以,很多类型的设计者可能并不知道该类型到底实现了哪些接口。

  3. Go是一门编译型语言,Go语言的工具链将源代码及其依赖转换成计算机的机器指令(静态编译)。
    每个源文件都以一条package声明语句开始,表示该文件属于哪个包。紧跟着一系列导入(import)的包,之后就是程序语句。
    import语句必须跟在文件的package声明之后,包导入顺序并不重要。

  4. Go语言不需要在语句或声明的末尾添加分号,除非一行上有多条语句。

  5. 实际上,编译器会主动把特定符号(比如,行末是标识符,整数,浮点数,虚数,字符或字符串文字,关键字,break,continue,fallthrough或return中的一个,运算符和分隔符,++,--,),] 或 } 中的一个)后的换行符转换为分号,因此换行符添加的位置会影响Go代码的解析。

  6. 程序的命令行参数可以从os包的Args变量获取。

  7. os.Args变量是一个字符串(string)的切片(slice)。

  8. 区间索引时s[m:n],Go语言也采用左闭右开形式(即,区间包括第一个索引元素,不包括最后一个),因为这样可以简化逻辑,比如s[m:n]这个切片,0<=m<=n<=len(s),包含n-m个元素,产生从第m个元素到n-1个元素的切片。

  9. os.Args的第一个元素,os.Args[0]是命令本身的名字,其它的元素则是程序启动时传给它的参数。
    os.Args[1:len(os.Args)] <==> os.Args[1:]

  10. gofmt 工具格式化时按照字母顺序对报名排序。

  11. i++和 i--在Go语言中是语句,而不像C系的其它语言那样是表达式,所以j=i++非法。
    ++和--只能放在变量名后面,因此 --i也非法。

for initialization; condition; post {
  //zero or more statements
}

for 循环三个部分不需要括号包围。大括号强制要求,左大括号必须和post语句在同一行。

initialization语句是可选的,在循环开始前执行,initialization如果存在,必须是一条简单语句(simple statement)即短变量声明、自增语句、赋值语句或函数调用。
condition 是一个布尔表达式(boolean expression),其值在每次循环迭代开始时计算,如果为true,则执行循环体语句。
post 语句在循环体执行结束后执行,之后再对condition求值,condition值为false时,循环结束。

for循环的这三个部分每个都可以省略。

13. range 产生一对值,索引以及在该索引处的元素值,其语法要求要处理元素必须处理索引。

14. Go语言不允许使用无用的局部变量。

15. 空标识符(blank identifier)即_(下划线)用于任何语法需要变量名但是程序逻辑不需要的时候。

16. 变量声明方式:

s := 0 //短变量声明,最简洁,但是只能用于函数内部,不能用于包变量
var s string  //依赖于字符串的默认初始化零值机制,被初始化为" "
var s = " " //用的很少,除非同时声明多个变量
var s string  = " " //显示标明变量的类型,当变量 类型与初值类型相同时,类型冗余,但是如果类型不同,变量类型就是必须的了。

17. map存储了键/值(key/value)集合,对集合元素,提供常数时间的存取或测试操作。
键可以是任意类型,只要其值能用==运算符比较,最常见的例子是字符串。
值可以是任意类型。

18. map 的迭代顺序并不确定。从实践来看,该顺序随机。每次运行都会变化,该设计是有意为之的,可以防止利用哈希碰撞的拒绝服务攻击。

19. fmt.Printf 函数对一些表达式产生格式化输出。该函数的首个参数是个格式字符串,指定后续参数被如何格式化。各个参数的格式取决于“转换字符串”(conversion character),形式为百分号后跟一个字母。
Printf 有一大堆这种转换。Go程序员称为为动词(verb)

%d                  // 十进制整数
%x,%o,%b     // 十六进制,八进制,二进制整数
%f,%g,%e     //浮点数:3.141593,3.141592653589793,3.141593e+00
%t                 // 布尔:true或false
%c                //字符(rune)(Unicode码点)
%s                //字符串
%q               // 带双引号的字符串“abc”或带单引号的 字符'c'
%v               // 变量的自然形式 (natural formal)
%T              //变量的类型
%%            //字面上的百分号标示(无操作数)

同时还包含有制表符\t和换行符\n,这些代表不可见字符的转义字符(escape sequences)

20. make函数创建数据结构的引用

21. 常量是指在程序编译后运行时始终都不会变化的值。
目前常量声明的值必须是一个数字值、字符值或者一个固定的booelan值。

22. goroutine 是一种函数的并发执行方式,而channel是用来在goroutine之间进行参数传递
main函数本身也运行在一个goroutine中,而go function 则表示创建一个新的goroutine,并且在这个新的goroutine中执行这个函数。

23. 当一个goroutine尝试在一个channel上做 send 或者 receive 操作时,这个goroutine会阻塞在调用处,直到另一个goroutine往这个channel里接收写入值,这样两个goroutine才会继续执行channel之后的逻辑。

24. Go语言中的switch还可以不带操作对象,此时默认用true来代替,然后将每个case的表达式和true值进行比较。

25. Go语言指针是可见的内存地址,&操作符可以返回一个变量的内存地址,并且 * 操作符可以获取指针指向的变量内容。但是Go语言中没有指针运算。

上一篇:聊聊 g0


下一篇:Go语言常见坑