Go学习笔记一:go语言基础
这是我学习go语言的第一篇读书笔记,主要学习go语言中的基础数据类型以及控制结构。
- 基本内置类型,比如整数,浮点数,布尔类型,字符串等。
- 容器结构,数组,切片,map
- if/else, for控制结构
基本内置类型
bool类型
func bool_test() {
var boolvar = true
fmt.Print(boolvar)
}
true
boolvar = 1
cannot use 1 (type int) as type bool in assignment
bool类型的数据只可以用true/false初始化,不支持非bool类型数据的赋值。也不支持强制类型转换。在C/C++中,由于一系列的默认转换,可以用非true/false来初始化布尔类型。相比而言,go更严格,更明确。
数学类型
int 根据平台架构确定数据长度 int8, int32, int64, uint8, uint32, uint64 确定长度的整数类型
float32, float64 确定长度的浮点数类型 complex64,complex128 复数 byte 等同于uint8
在以后的实际开发中,我们可以根据实际需求直接使用带有长度的类型。代码的可读性也很好。建议在C/C++代码中也直接如此使用。
Go语言不支持不同类型间的隐式转换,如果要在不同类型的数据之间进行运算,请先统一数据类型。
字符串类型
在GO中,string类型的数据,一旦赋值后不可更改。如果需要编辑字符串,可以转为数组后再行编辑功能。
content := "this is my string conent"
content[1] = 'c'
报错,.\stringtest.go:10: cannot assign to content[1],不可以赋值。
content := "this is my string conent"
str_array := []rune(content)
fmt.Println(str_array)
str_array[1] = 'c'
fmt.Print(str_array)
[116 104 105 115 32 105 115 32 109 121 32 115 116 114 105 110 103 32 99 111 110 101 110 116]
[116 99 105 115 32 105 115 32 109 121 32 115 116 114 105 110 103 32 99 111 110 101 110 116]
可见str_array[1]确实变了。
控制结构
顺序结构
此处不用多说,程序按代码编写的顺序先后执行即可。
分支结构if/else
a := 10
if a < 10 {
fmt.Printf("\n a < 10\n")
} else if a == 10 {
fmt.Printf("\n a == 10")
} else {
fmt.Printf("\n a > 10")
}
a == 10
分支结构 switch/case
switch/case的作用其实与if/else作用是一致的,就是用来做分支控制。
该种分支结构和C语言中的switch case语句是一样的,通过匹配a 和case中的值来执行相关语句。
a = 30
switch a {
case 29:
fmt.Print("\nvalue:29")
case 30:
fmt.Print("\nvalue 30")
}
还有一种switch语句是带判断条件
switch {
case a < 30:
fmt.Print("\na < 30")
case a == 30:
fmt.Printf("\na == 30")
}
其实不管哪一种switch case语句,其实都可以用if/else结构实现。在实际中我使用switch case的机会好像很少,几乎不用。
循环结构 for
go语言中没有while, do while等语句,统一采用for来实现循环操作,这种方式我觉得很好,用for统一循环结构。 此处用go中的for循环实现了0~99相加求和的操作。
i := 0
sum := 0
for i = 0; i < 100; i++ {
sum += i
}
fmt.Printf("\nsum = %d", sum)
sum = 4950
内置容器结构
数组
数组在定义之初就会确定空间大小,并可以通过len获取数组长度,通过range进行数组遍历。
func int_array_test() {
var intarray [32]int
var i int = 0
for i = 0; i < len(intarray); i++ {
intarray[i] = i
}
fmt.Println(intarray)
index := 0
value := 0
for index, value = range intarray {
fmt.Printf("arr[%d]=%d \n", index, value)
}
}
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]
arr[0]=0
arr[1]=1
arr[2]=2
arr[3]=3
arr[4]=4
arr[5]=5
......
arr[29]=29
arr[30]=30
arr[31]=31
切片
数组定义好之后,空间大小不好再改变,但是联想到易用性,在C++中出现了vector这样易用加强型的数组,go语言同样不甘落后,提供了数组切片这样的对象。
创建切片, 并对其进行扩容,可见slice是一个可以动态变化的对象。
//创建指定大小的切片
s := make([]int, 3)
s[0] = 0
s[1] = 1
s[2] = 2
fmt.Print(s)
fmt.Print(len(s))
fmt.Println("\n")
//对切片进行动态扩展
s = append(s, 3)
s = append(s, 4)
fmt.Print(s)
fmt.Print(len(s))
[0 1 2]3
[0 1 2 3 4]5
map
map是一种key-value结构的数据结构,可参考C++中std::map的用法,思想一致,这是高频使用的的一种数据结构,所以go语言直接做到了语言级支持,而无需通过库。
//创建key-value 容器, key:string value int
mymap := make(map[string]int)
mymap["math"] = 90
mymap["yuwen"] = 99
mymap["zhenzhi"] = 70
fmt.Print(mymap)
练习
Q1. (0) For-loop
- 创建一个基于 for 的简单的循环。使其循环 10 次,并且使用 fmt 包打印出计数 器的值。
- 用 goto 改写 1 的循环。关键字 for 不可使用。
- 再次改写这个循环,使其遍历一个 array,并将这个 array 打印到屏幕上
func looptest() {
fmt.Println("looptest")
for i := 0; i < 10; i++ {
fmt.Println(i)
}
}
func gotest() {
fmt.Println("goto test")
var i = 0
loop:
if i < 10 {
fmt.Println(i)
i++
goto loop
}
}
func arraytest() {
fmt.Print("arraytest")
var collection [10]int32
var j int32 = 0
for j = 0; j < 10; j++ {
collection[j] = j
}
fmt.Print(collection)
}
Q2. (0) FizzBuzz
- 解决这个叫做 Fizz-Buzz[23] 的问题: 编写一个程序,打印从 1 到 100 的数字。当是三的倍数就打印 “Fizz” 代替数字,当是ࡃ的়数就打印 “Buzz”。当数字同时是三和ࡃ的়数 时,打印 “FizzBuzz”。
func FizzBuzz() {
for i := 0; i < 100; i++ {
if i%3 == 0 && i%5 == 0 {
fmt.Print("FizzBuzz")
} else if i%3 == 0 {
fmt.Print("Fizz")
} else if i%5 == 0 {
fmt.Print("Buzz")
} else {
fmt.Print(i)
}
}
}
Q3. 1.编写一个 Go 程序可以逆转字符串,例如 “foobar” 被打印成 “raboof”。 提示: 不幸的是你需要知道一些关于转换的内容,参阅 “转换” 第 59 页的内容。
func exchage(conent string) string {
a := []rune(conent)
arraySize := len(a)
for i, j := 0, arraySize-1; i <= j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
return string(a)
}
此处让我震惊的是在go语言中,交换数据,可以直接采用a[i],a[j] = a[j], a[i]进行数据交换。
附录:
go中同样提供了比如复数等数据类型,但是我在实际工作中并不会用到,所以文中并没有做说明。