漫游Go语言(一)之包,函数&变量
这只是我follow tour.golang.org时的笔记(翻译)。
Package
Go程序都由包组成,从main
包开始执行。1
2
3
4
5
6
7
8
9
10package 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
10package 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
10package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math.Pi)
}
运行以上代码会报以下错误:1
2
3
4prog.go:9: cannot refer to unexported name math.pi
prog.go:9: undefined: math.pi
Program exited.
将pi改为Pi即可正常运行。
Functions
除了变量(返回)类型在变量(函数)名之后,函数的声明与其它类C语言无异。
1 | package main |
当有多个变量名同类型时,可以一起指定类型1
2
3
4
5
6
7
8
9
10
11package main
import "fmt"
func add(x, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
Go函数还可以返回多个值
1 | package main |
Go还可以对返回值命名,并使用裸return语句来返回它们1
2
3
4
5
6
7
8
9
10
11
12
13package 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 | package main |
变量初始化
var
声明也可以包含初始值,此时可以省略类型,变量将使用初始值的类型。1
2
3
4
5
6
7
8
9
10package 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 | package main |
而在函数外,所有语句都必须以var
,func
等等关键字开头
基本数据类型
Go有如下基本数据类型1
2
3
4
5
6
7
8
9
10
11
12
13
14
15bool
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
19package 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
30 for numeric types,
false the boolean type, and
"" (the empty string) for strings.
类型转换
表达式T(v)
代表类型转换。
1 | var i int = 42 |
和C不同的是Go必须显式地进行类型转换,否则出错。
类型推断
当隐式定义变量时,其类型由右边值来确定,当右边为常数时,默认其类型为int
,float
64, or complex128
。1
2
3
4
5
6
7
8package main
import "fmt"
func main() {
v := 3.14 + 1i// change me!
fmt.Printf("v is of type %T\n", v)
}
运行结果:1
2
3v is of type complex128
Program exited.
Printf中%T输出变量类型,注意复数i前面必须有数字,否则将被识别是变量而报错。
常量
常量与变量定义方式类型,但使用const关键字,同时常量不能用:=
来定义。1
2
3
4
5
6
7
8
9
10
11
12
13
14package 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
22package 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
521
0.2
1.2676506002282295e+29
Program exited.