本节包括 Go 的基本数据类型、变量与常量、运算符、控制结构、函数等内容。
1 基本数据类型h2
Go 中的基本数据类型只有三种:布尔型、数字类型、字符串类型。
布尔型即true或false。
常用的数字类型有int、float32 和float64。
字符串型string就是一串固定长度的单个字符连接起来的字符序列。
int只是一个别名,在 32 位系统和 64 位系统中分别代表int32和int64。除了这两者以外,Go 还有uint8 uint16 uint32 uint64 int8 int16 int32 int64 。
除此之外,Go 还支持复数类型complex64 complex128 。
2 变量与常量h2
2.1 变量h3
Go 通常使用var关键字来声明一个变量:
var name string = "YOAKE"var age int = 23var isStudent bool = true你当然也可以不选择初始化。不带初始化声明的变量为零值(数字0、空字符串""或false)。
如果你比较懒,不想写类型。Go 会根据初始化时所赋值的类型自动推断该变量的类型。
var name = "YOAKE"
name = 1 // Error: cannot use 1 (untyped int constant) as string value in assignment不过既然类型能自动推断,那么var关键字就显得有些多余了。因此 Go 有:=操作符:
name := "YOAKE"age := 23isStudent := true现在你应该体会到 Go 的简洁和优雅了。虽然:=操作符很好用,但是它只能在函数体中使用,因此不能使用它来定义全局变量(虽然也不建议在任何时候定义全局变量)。
当然也有多变量声明,出始值会按照顺序依次赋给各个变量:
name, age, isStudent := "YOAKE", 23, trueGo 也提供了多变量赋值功能,你可以像写 Python 那样交换两个变量的值:
a, b := 1, 2a, b = b, a // a: 2, b: 1你可能已经发现了,如果你定义了一个变量却没有使用的话,就会报错:
a, b := 1, 2 // declared and not used: afmt.Println("b:", b)这是因为 Go 强制要求你必须使用所有被声明的变量。
2.2 常量h3
常量使用const来声明,你也可以不用写它的类型:
const NAME = "YOAKE"const AGE = 23const IS_STUDENT = true3 运算符h2
Go 的运算符和其他的都大差不差:
- 算术运算符:
+-*/%++-- - 关系运算符:
==!=><>=<= - 逻辑运算符:
&&||! - 位运算符:按位与
&、按位或|、按位异或^、左移<<、右移>> - 赋值运算符:
=+=-=*=/=%=<<=>>=&=^=|=
此外,Go 中是有指针的,因此有指针运算符:
*a:指针变量;&a:变量的实际地址。
4 控制结构h2
if-else语句 for循环 switch语句
4.1 if-elseh3
结构和其他语言类似,需要注意的是布尔表达式没有括号:
age := 23
if age < 18 { fmt.Println("未成年")} else { fmt.Println("成人")}4.2 switchh3
和其他语言也差不多,不过没有break语句。因此匹配某一分支成功后就不会执行其他(后续)的分支。
score := 85
switch { case score >= 90: fmt.Println("Grade: A") case score >= 80: fmt.Println("Grade: B") case score >= 70: fmt.Println("Grade: C") case score >= 60: fmt.Println("Grade: D") default: fmt.Println("Grade: F")}4.3 forh3
Go 的 for 循环有三种形式,分别是:
- 传统的 for 循环:
for index := 0; index < 10; index ++ { }- while 风格的循环:
index := 0for index < 10 { // existing code index ++}- 死循环:
for {}和其他现代语言一样,Go 也支持字符串、数组等结构的 for-each 迭代:
numbers := [5]int{1, 2, 3, 4, 5}
for index, num := range numbers{ fmt.Printf("第 %d 位的值为", index, num)}5 函数h2
5.1 函数的声明h3
Go 在声明函数时要写明参数类型和返回值类型:
func add(x int, y int) int { return x + y}如果参数都是相同类型,则可以简写:
func add(x, y int) int { return x + y}其实也和其他语言差不多。但是 Go 的函数可以返回多个值,就像 Python 一样:
func addAndMulti(x int, y int) (int, int) { return x + y, x * y}同理,你也要依次写上返回值的类型。
_有时候我们不想使用函数的全部返回值,就可以用_来选择性地丢弃。例如:
addResult, _ = addAndMulti(3, 5)这样我们就安全地丢弃了我们不想要的第二个返回值。
5.2 匿名函数h3
Go 语言中将函数视为一等公民,这就让匿名函数变得非常好用,就像 TypeScript:
add := func(a, b int) int { return a + b}
result := add(1, 2)你一定和我有一样的想法:那我所有的函数都用匿名函数来写并且赋值就好了,统一、美观。
别这样做。在 Go 中,坚持使用具名函数是绝对的主流。
有了匿名函数,就可以写闭包:
func intSeq() func() int { i := 0 return func() int { i++ // 匿名函数引用了外部的 i return i }}
func main() { nextInt := intSeq() // nextInt 变成了一个闭包
fmt.Println(nextInt()) // 1 fmt.Println(nextInt()) // 2}也可以作为回调函数:
func visit(numbers []int, f func(int)) { for _, n := range numbers { f(n) }}
visit([]int{1, 2, 3}, func(n int) { fmt.Println(n * n)})