这只是我follow tour.golang.org时的笔记(翻译)。
Package
Go程序都由包组成,从main
包开始执行。
1 2 3 4 5 6 7 8 9 10
| package main import ( "fmt" "math/rand" ) func main() { fmt.Println("My favorite number is", rand.Intn(10)) }
|
以上程序导入了match
和math/rand
两个包,按约定包名与路径最后一部分相同,比如math/rand
目录下的文件都以package rand的声明开头。
Import
可以将多个包用括号一起导入,如
1 2 3 4 5 6 7 8 9 10
| package main import ( "fmt" "math" ) func main() { fmt.Printf("Now you have %g problems.", math.Sqrt(7)) }
|
当然也可以用多个语句分别导入,但推荐以上方式。
Exported Names
在Go中,如果一个名字以大写形状,那么这是一个导出名。
当导入一个包时,只有exported Names可被访问,否则会报错。
1 2 3 4 5 6 7 8 9 10
| package main import ( "fmt" "math" ) func main() { fmt.Println(math.Pi) }
|
运行以上代码会报以下错误:
1 2 3 4
| prog.go:9: cannot refer to unexported name math.pi prog.go:9: undefined: math.pi Program exited.
|
将pi改为Pi即可正常运行。
Functions
除了变量(返回)类型在变量(函数)名之后,函数的声明与其它类C语言无异。
1 2 3 4 5 6 7 8 9 10 11
| package main import "fmt" func add(x int, y int) int { return x + y } func main() { fmt.Println(add(42, 13)) }
|
当有多个变量名同类型时,可以一起指定类型
1 2 3 4 5 6 7 8 9 10 11
| package main import "fmt" func add(x, y int) int { return x + y } func main() { fmt.Println(add(42, 13)) }
|
Go函数还可以返回多个值
1 2 3 4 5 6 7 8 9 10 11 12
| package main import "fmt" func swap(x, y string) (string, string) { return y, x } func main() { a, b := swap("hello", "world") fmt.Println(a, b) }
|
Go还可以对返回值命名,并使用裸return语句来返回它们
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main import "fmt" func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return } func main() { fmt.Println(split(17)) }
|
不建议在行数很多的函数中使用裸return
,会损害可读性。
Variables
使用var可以定义一组用逗号’,’隔开的变量,同样类型放在最后,变量作用域可以是包也可以是函数。
变量声明
1 2 3 4 5 6 7 8 9 10
| package main import "fmt" var c, python, java bool func main() { var i int fmt.Println(i, c, python, java) }
|
变量初始化
var
声明也可以包含初始值,此时可以省略类型,变量将使用初始值的类型。
1 2 3 4 5 6 7 8 9 10
| package main import "fmt" var i, j int = 1, 2 func main() { var c, python, java = true, false, "no!" fmt.Println(i, j, c, python, java) }
|
短变量声明
在函数中可以使用:=
代替var
关键字来隐式声明变量。
1 2 3 4 5 6 7 8 9 10 11
| package main import "fmt" func main() { var i, j int = 1, 2 k := 3 c, python, java := true, false, "no!" fmt.Println(i, j, k, c, python, java) }
|
而在函数外,所有语句都必须以var
,func
等等关键字开头
基本数据类型
Go有如下基本数据类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // alias for uint8 rune // alias for int32 // represents a Unicode code point float32 float64 complex64 complex128
|
在以下例子中展示了几种数据类型,并使用了var
+块的方式来定义变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package main import ( "fmt" "math/cmplx" ) var ( ToBe bool = false MaxInt uint64 = 1<<64 - 1 z complex128 = cmplx.Sqrt(-5 + 12i) ) func main() { const f = "%T(%v)\n" fmt.Printf(f, ToBe, ToBe) fmt.Printf(f, MaxInt, MaxInt) fmt.Printf(f, z, z) }
|
通常int
,uint
和uintptr
在32/64位机器上是32/64位的。一般来说无特殊需求时使用int
即可。
0默认初值
如果声明变量时不指定初值,那么默认值为0,具体含义为
1 2 3
| 0 for numeric types, false the boolean type, and "" (the empty string) for strings.
|
类型转换
表达式T(v)
代表类型转换。
1 2 3 4 5 6 7
| var i int = 42 var f float64 = float64(i) var u uint = uint(f) i := 42 f := float64(i) u := uint(f)
|
和C不同的是Go必须显式地进行类型转换,否则出错。
类型推断
当隐式定义变量时,其类型由右边值来确定,当右边为常数时,默认其类型为int
,float
64, or complex128
。
1 2 3 4 5 6 7 8
| package main import "fmt" func main() { v := 3.14 + 1i// change me! fmt.Printf("v is of type %T\n", v) }
|
运行结果:
1 2 3
| v is of type complex128 Program exited.
|
Printf中%T输出变量类型,注意复数i前面必须有数字,否则将被识别是变量而报错。
常量
常量与变量定义方式类型,但使用const关键字,同时常量不能用:=
来定义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package main import "fmt" const Pi = 3.14 func main() { const World = "世界" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day") const Truth = true fmt.Println("Go rules?", Truth) }
|
数值常量
数值常量是高精度值,未指定具体类型的常量会自动适应上下文环境。
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" const ( // Create a huge number by shifting a 1 bit left 100 places. // In other words, the binary number that is 1 followed by 100 zeroes. Big = 1 << 100 // Shift it right again 99 places, so we end up with 1<<1, or 2. Small = Big >> 99 ) func needInt(x int) int { return x*10 + 1 } func needFloat(x float64) float64 { return x * 0.1 } func main() { fmt.Println(needInt(Small)) fmt.Println(needFloat(Small)) fmt.Println(needFloat(Big)) }
|
运行结果:
1 2 3 4 5
| 21 0.2 1.2676506002282295e+29 Program exited.
|