golang圣经第一章:入门
对go的一些样例做基本的介绍
Go语言(或 Golang)起源于 2007 年,并在 2009 年正式对外发布。Go 是非常年轻的一门语言,它的主要目标是“兼具 Python 等动态语言的开发速度和 C/C++ 等编译型语言的性能与安全性”。
1.1 hello world
go是静态编译
go run test.go
go build test.go
go build会生成可执行的二进制文件
必须恰当导入需要的包,缺少了必要的包或者导入了不需要的包,程序都无法编译通过。这项严格要求避免了程序开发过程中引入未使用的包(Go 语言编译过程没有警告信息,争议特性之一)。
换行符
Go 语言不需要在语句或者声明的末尾添加分号,除非一行上有多条语句。实际上,编译器会主动把特定符号后的换行符转换为分号,因此换行符添加的位置会影响 Go 代码的正确解析
函数的左括号 { 必须和 func 函数声明在同一行上,且位于末尾,不能独占一行,而在表达式 x+y 中,可在 + 后换行,不能在 + 前换行(译注:以+结尾的话不会被插入分号分隔符,但是以 x 结尾的话则会被分号分隔符,从而导致编译错误)。
代码编辑器会自动调用gofmt工具把代码格式化为标准格式,这个格式化工具没有任何可以调整代码格式的参数,固定死的
Go原生支持unicode
1.2 命令行参数
数组
go语言采用左闭右开形式
s[m:n] 这个切片,0≤m≤n≤len(s),包含 n-m 个元素。
如果省略切片表达式的 m 或 n,会默认传入 0 或 len(s),因此前面的切片可以简写成 os.Args[1:]
os包
命令行参数可以从os包的Args变量获取
os.Args是一个字符串的切片
os.Args[0]//命令本身的名字
++–
自增语句 i++ 给 i 加 1
这和 i+=1 以及 i=i+1 都是等价的。对应的还有 i-- 给 i 减 1。它们是语句,而不像 C 系的其它语言那样是表达式。
所以 j=i++ 非法,而且 ++ 和 -- 都只能放在变量名后面,因此 --i 也非法。
循环
go只有for循环
显示索引
for initialization; condition; post {
// zero or more statements
}
for 循环三个部分不需括号包围。大括号强制要求,左大括号必须和 post 语句在同一行。
initialization 语句是可选的,在循环开始前执行。initalization 如果存在,必须是一条 简单语句(simple statement),即,短变量声明、自增语句、赋值语句或函数调用。condition 是一个布尔表达式(boolean expression),其值在每次循环迭代开始时计算。如果为 true 则执行循环体语句。post 语句在循环体执行结束后执行,之后再次对 condition 求值。condition 值为 false 时,循环结束。
for 循环的这三个部分每个都可以省略,如果省略 initialization 和 post,分号也可以省略:
// a traditional "while" loop
for condition {
// ...
}
如果连 condition 也省略了,像下面这样:
// a traditional infinite loop
for {
// ...
}
这就变成一个无限循环,尽管如此,还可以用其他方式终止循环,如一条 break 或 return 语句。
隐式索引
for 循环的另一种形式,在某种数据类型的区间(range)上遍历,如字符串或切片。echo 的第二版本展示了这种形式:
// Echo2 prints its command-line arguments.
package main
import (
"fmt"
"os"
)
func main() {
s, sep := "", ""
for _, arg := range os.Args[1:] {
s += sep + arg
sep = " "
}
fmt.Println(s)
}
每次循环迭代,range 产生一对值;索引以及在该索引处的元素值。这个例子不需要索引,但 range 的语法要求,要处理元素,必须处理索引。一种思路是把索引赋值给一个临时变量(如 temp)然后忽略它的值,但 Go 语言不允许使用无用的局部变量(local variables),因为这会导致编译错误。
Go 语言中这种情况的解决方法是用 空标识符(blank identifier),即 _(也就是下划线)。空标识符可用于在任何语法需要变量名但程序逻辑不需要的时候(如:在循环里)丢弃不需要的循环索引,并保留元素值。大多数的 Go 程序员都会像上面这样使用 range 和 _ 写 echo 程序,因为隐式地而非显式地索引 os.Args,容易写对。
变量声明
声明一个变量有好几种方式,下面这些都等价:
s := ""
var s string
var s = ""
var s string = ""
第一种形式,是一条短变量声明,最简洁,但只能用在函数内部,而不能用于包变量。
第二种形式依赖于字符串的默认初始化零值机制,被初始化为 ""。
第三种形式用得很少,除非同时声明多个变量。
第四种形式显式地标明变量的类型,当变量类型与初值类型相同时,类型冗余,但如果两者类型不同,变量类型就必须了。
实践中一般使用前两种形式中的某个,初始值重要的话就显式地指定变量的类型,否则使用隐式初始化。
1.3 查找重复的行
动词
%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 format)
%T 变量的类型
%% 字面上的百分号标志(无操作数)
格式化函数
默认情况下,Printf 不会换行。按照惯例,以字母 f 结尾的格式化函数,如 log.Printf 和 fmt.Errorf,都采用 fmt.Printf 的格式化准则。而以 ln 结尾的格式化函数,则遵循 Println 的方式,以跟 %v 差不多的方式格式化参数,并在最后添加一个换行符。(译注:后缀 f 指 format,ln 指 line。)
nil
nil属于内置值,相当于其他语言中的NULL