一、HelloWorld
“HelloWorld”是程序员对这个世界的第一次呐喊,所以学习这门语言之初,我们就从hello.go开始吧!
在GO语言里,命名为main的包具有特殊的含义,Go语言的编译程序会试图把这种名字的包编译为二进制可执行文件,所有用Go语言编译的可执行程序都必须有一个名叫main的包,一个可执行程序有且仅有一个main包。
当编译器发现某个包的名字为main时,它一定也会发现名为main()的函数,否则不会创建可执行文件。main()函数是程序的入口,所以,如果没有这个函数,程序就没有办法开始执行,程序编译时,会使用声明main包的代码所在的目录名作为二进制可执行文件的文件名。
二、基础语法
1.变量
所谓变量,就是可以变化的量。使用var关键字定义函数,函数可以有参数和返回值。函数可以是包级别的,也可以是局部的。例如:func add(a, b int) int { return a + b }。
这是一个简单的Go语言程序。下面是对程序进行逐行解释。(解释的序号与代码前的行数一致,方便大家查看)
1.package main 表示这个文件属于 main 包,main是一个特殊的包名,它标识这个文件是一个可执行的程序,而不是一个库文件。
3.使用 import 关键字导入了两个包,fmt 和 math。 fmt 包提供了基本的格式化和输入输出功能,math 包提供了数学函数。
7.func main() 是主函数的定义,是程序执行的入口。
8.var a = "initial" 声明并初始化了一个变量 a,其类型会从初始值进行推断。
9.var b, c int = 1, 2 声明并初始化了两个整型变量 b 和 c。
10.var d = true 声明并初始化了一个布尔型变量 d。
11.var e float64 声明了一个浮点型变量 e,未给其赋初值。默认为该类型的零值。
13.f := float32(e) 声明并初始化了一个浮点型变量 f,其值从 e 进行类型转换。
14.g := a + "foo" 声明并初始化了一个字符串变量 g,其值由 a 和字面值 "foo" 拼接而成。
15.fmt.Println 函数用来将结果输出到标准输出,这里输出了上述变量的值。
16.const 关键字用于声明常量,s 是一个字符串常量,h 是一个整型常量,i 是一个浮点型常量。
18、19、20. 再次使用 fmt.Println 输出常量 s、 h、 i、 math.Sin(h) 和 math.Sin(i) 的值。
总的来说,这个程序演示了Go语言中的变量声明、类型推断、常量和基本的输出功能。
2.if else
这是一个简单的Go语言程序,演示了条件语句的使用。下面是对程序进行逐行的解释:
if 7%2 == 0 是一个条件语句,判断 7 是否能被 2 整除。如果条件为真,则执行 {} 内的代码块;否则执行 else 后的代码块。
if 8%4 == 0 同样是一个条件语句,判断 8 是否能被 4 整除。条件为真,则执行 {} 内的代码块。
if num := 9; num < 0 是一个带有初始化语句的条件语句。首先,定义了一个变量 num 并赋值为 9。然后判断 num 是否小于 0,如果条件为真,则执行 {} 内的代码块。如果条件为假,则判断 num 是否小于 10,如果条件为真,则执行下一个代码块;如果条件都不满足,则执行 else 后的代码块。
3.循环
这是一个使用循环的Go语言程序。下面是对程序进行逐行的解释:
i := 1
for {
fmt.Println("loop")
break
}
这段代码使用了一个无限循环,并在循环体内打印出字符串 "loop"。然后,通过 break 关键字退出循环。
for j := 7; j < 9; j++ {
fmt.Println(j)
}
这段代码使用了一个简单的 for 循环, j 的初始值为 7,每次循环后 j 的值加 1。循环的条件是j小于 9。在循环体内,打印出 j 的值。
for n := 0; n < 5; n++ {
if n%2 == 0 {
continue
}
fmt.Println(n)
}
这段代码使用了一个 for 循环,n 的初始值为 0,每次循环后 n 的值加 1。循环的条件是 n 小于 5。在循环体内,判断n是否为偶数,如果是偶数,则使用 continue 关键字跳过本次循环。如果是奇数,则打印出n的值。
for i <= 3 {
fmt.Println(i)
i = i + 1
}
这段代码使用了一个 for 循环,循环的条件是 i 小于等于 3。在循环体内,打印出 i 的值,然后将 i 的值加 1。循环会一直执行,直到 i 大于 3。
总的来说,这个程序演示了Go语言中不同类型的循环语句的使用,包括无限循环、带有计数器的循环、跳过循环和基于条件的循环。
4.switch
这是一个使用 switch 语句的Go语言程序。下面是对程序进行逐行的解释:
a := 1
switch a {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
case 4, 5:
fmt.Println("four or five")
default:
fmt.Println("other")
}
这段代码使用了 switch 语句根据变量 a 的值执行不同的代码分支。当 a 的值为 1 时,输出 "one";当 a 的值为 2 时,输出 "two";当 a 的值为 3 时,输出 "three";当 a 的值为 4 或 5 时,输出 "four or five";其他情况下,输出 "other"。
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
这段代码使用了一个不带条件的 switch 语句来根据当前时间判断是上午还是下午。如果当前时间的小时数小于 12,输出 "It's before noon";否则,输出 "It's after noon"。
总的来说,这个程序演示了不同情况下使用 switch 语句的能力,它可以根据变量的值或条件来决定执行的代码分支。
5.数组
这是一个关于数组的Go语言程序。下面是对程序进行逐行的解释:
var a [5]int
a[4] = 100
fmt.Println(a[4], len(a))
这段代码定义了一个长度为 5 的整数数组 a。然后,将数组中索引为 4 的元素赋值为 100。接着,通过打印 a[4] 和 len(a),输出数组中索引为 4 的元素的值(即 100)和数组的长度(即 5)。
b := [5]int{1, 2, 3, 4, 5}
fmt.Println(b)
这段代码定义了一个长度为 5 的整数数组 b,并初始化数组的值为 {1, 2, 3, 4, 5}。然后,通过打印 b,输出整个数组的值。
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d:", twoD)
这段代码定义了一个二维整数数组 twoD,大小为 2x3,即两行三列。接着,通过两个嵌套的 for 循环,遍历数组中的每一个元素,并将两个索引的和赋值给数组的对应元素。最后,通过打印 twoD,输出整个二维数组的值。
总的来说,这个程序演示了在Go语言中声明、初始化和访问数组的方法,以及如何操作二维数组。
6.切片
这是一个关于切片的Go语言程序。下面是对程序进行逐行的解释:
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])
fmt.Println("len:", len(s))
这段代码使用 make 函数创建了一个长度为 3 的切片 s。然后,分别给切片的索引为 0、1 和 2 的位置赋值为 "a"、"b" 和 "c"。接着,通过打印 s[2],输出切片中索引为 2 的元素的值(即 "c")。再通过打印 len(s),输出切片的长度(即 3)。
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s)
这段代码使用 append 函数向切片 s 中追加了元素。首先,追加了一个元素 "d";然后,追加了两个元素 "e" 和 "f"。最后,通过打印 s,输出追加后的切片。
c := make([]string, len(s))
copy(c, s)
fmt.Println(c)
这段代码使用 make 函数创建了一个与切片 s 长度相同的切片 c。然后,使用 copy 函数将切片 s 的内容复制到切片 c 中。最后,通过打印 c,输出复制后的切片。
fmt.Println(s[2:5])
fmt.Println(s[:5])
fmt.Println(s[2:])
这段代码演示了切片的切割操作。s[2:5] 表示从切片 s 中索引为 2(包含)到索引为 5(不包含)的子切片;s[:5] 表示从切片 s 的开头开始到索引为 5(不包含)的子切片;s[2:] 表示从切片 s 索引为 2(包含)到末尾的子切片。通过打印这些子切片,输出相应的结果。
good := []string{"g", "o", "o", "d"}
fmt.Println(good)
这段代码创建了一个字符串切片 good,并初始化了切片的值为 {"g", "o", "o", "d"}。然后,通过打印 good,输出整个切片的值。
总的来说,这个程序演示了在Go语言中使用切片的各种操作,包括创建切片、获取切片元素、追加元素、复制切片以及对切片进行切割。
7.map
这是一个关于映射(map)的Go语言程序。下面是对程序进行逐行的解释:
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m)
fmt.Println(len(m))
fmt.Println(m["one"])
fmt.Println(m["unknown"])
这段代码使用 make 函数创建了一个新的映射 m,键的类型为 string,值的类型为 int。然后,给映射 m 分别赋值为 {"one":1, "two":2}。通过打印 m,输出整个映射的键值对。接着,通过打印 len(m),输出映射的键值对数量。然后,通过打印 m["one"],输出映射中键为 "one" 对应的值。最后,通过打印 m["unknown"],输出映射中不存在的键对应的值(值的类型的零值)。
r, ok := m["unknown"]
fmt.Println(r, ok)
这段代码演示了通过访问映射的方式来获取值,并检查是否存在对应的键。首先,通过 m["unknown"] 获取键为 "unknown" 的值,然后将该值赋给变量 r。同时,通过 ok 变量接收一个布尔值,表示是否成功获取到键的值。通过打印 r 和 ok,即可输出相应的结果。
delete(m, "one")
这段代码使用 delete 函数从映射 m 中删除键为 "one" 的键值对。
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3)
这段代码演示了不同的创建映射的方式。m2 是使用字面值初始化的映射,键为 "one" 和 "two",相应的值为 1 和 2。m3 是使用显式类型声明并使用字面值初始化的映射。通过打印 m2 和 m3,输出所有的键值对。
总的来说,这个程序演示了在Go语言中使用映射的各种操作,包括创建映射、给键赋值、获取映射的长度、通过键获取对应的值、检查映射中是否存在某个键、删除键值对以及不同方式的映射创建。
8.range
这是一个关于使用循环遍历切片和映射的Go语言程序。下面是对程序进行逐行的解释:
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num)
}
}
fmt.Println(sum)
这段代码创建了一个整型切片 nums,并初始化了切片的值为 {2, 3, 4}。然后,定义一个整型变量 sum 并初始化为0。通过 range 关键字遍历切片 nums,同时获取元素的索引i和对应的值 num。在循环中,将当前值 num 累加到变量 sum 中。如果 num 的值等于2,就通过打印语句输出索引和值。最后,通过打印 sum,输出切片中所有元素的和。
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v)
}
这段代码创建了一个字符串映射 m,并初始化了映射的键值对为 {"a": "A", "b": "B"}。通过 range 关键字遍历映射 m,同时获取键 k 和对应的值 v,然后通过打印语句输出键和值。
for k := range m {
fmt.Println("key", k)
}
这段代码通过 range 关键字遍历映射 m 中的键,并将键赋给变量 k。然后通过打印语句输出键。
总的来说,这个程序演示了如何使用循环遍历切片和映射,并在遍历过程中对元素进行操作,例如累加求和、打印特定值和打印键值对。
9.函数
这是一个使用函数的Go语言程序。下面是对程序进行逐行的解释:
func add(a int, b int) int {
return a + b
}
这段代码定义了一个名为 add 的函数,接受两个整型参数 a 和 b,并返回它们的和。
func add2(a, b int) int {
return a + b
}
这段代码定义了一个名为 add2 的函数,与上面的 add 函数相比,省略了参数的类型声明,因为它们都是同一类型。
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
这段代码定义了一个名为 exists 的函数,接受一个字符串映射 m 和一个字符串键 k,并返回映射中对应键的值和一个布尔值,表示是否存在该键。在函数内部,通过 m[k] 获取键对应的值,并将值和一个布尔值赋给变量 v 和 ok,然后将它们作为结果返回。
func main() {
res := add(1, 2)
fmt.Println(res)
v, ok := exists(map[string]string{"a": "A"}, "a")
fmt.Println(v, ok)
}
这段代码在 main 函数中调用了上面定义的 add 函数和 exists 函数。将调用 add(1, 2) 的结果赋给变量 res,然后通过打印语句输出结果。接着,调用 exists 函数,并将返回的值赋给变量 v 和 ok,然后通过打印语句输出这两个变量的值。
总的来说,这个程序演示了如何定义和使用函数,包括函数的参数和返回值的声明,以及函数的调用和结果的处理。
由于内容太长,打算分两部分发布,期待下一次的分享......