# Go语言基础语法(一) 本文介绍一些Go语言的基础语法。 ## go简单小例子 先来看一个简单的go语言代码: ```go package main import "fmt" // 加法运算 func add(x, y int) int { return x + y } func init() { fmt.Println("main init....") } func main() { var value1 int = 2 var value2 = 3 sum := add(value1,value2) fmt.Printf("%d + %d = %d",value1,value2,sum) } ``` - `package main`:定义package 包名称为main,表示当前文件所属的包 - `import "fmt"`:导入Go标准库中的 fmt 模块,主要用于打印输出。go提供了很多标准库,具体可参考[Golang标准库文档](https://studygolang.com/pkgdoc)。 - `init()`:init()函数在main()函数之前执行。 - `main()`:main函数,是当前程序的入口,init()以及main()函数都无法被显式的调用。 go语言的注释方法: - 单行注释:`//` - 多行注释:`/* */` 代码执行结果: ```bash $ go run demo.go main init.... 2 + 3 = 5 ``` 下面来进一步介绍go的基础语法。 ## 格式化输出 go语言中格式化输出可以使用 fmt 和 log 这两个标准库, ### fmt 常用方法: - `fmt.Printf`:格式化输出 - `fmt.Println`:仅打印,不能转义,会在输出结束后添加换行符。 - `fmt.Print`:和Println类似,但不添加换行符。 - `fmt.Sprintf`:格式化字符串并赋值给新的字符串 示例代码: ```go package main import ( "fmt" ) func main() { var age = 22 fmt.Printf("I'm %d years old\n", age) str1 := "Hello world !" fmt.Printf("%s\n", str1) fmt.Printf(str1) fmt.Print("\n") str_hex := fmt.Sprintf("% 02x", str1) fmt.Printf("type of str_hex: %T\n", str_hex) fmt.Println(str_hex) } ``` 执行结果: ```go I'm 22 years old Hello world ! Hello world ! type of str_hex: string 48 65 6c 6c 6f 20 77 6f 72 6c 64 20 21 ``` 更多格式化方法可以访问[https://studygolang.com/pkgdoc](https://studygolang.com/pkgdoc)中的fmt包。 ### log log包实现了简单的日志服务,也提供了一些格式化输出的方法。 - `log.Printf`:格式化输出,和fmt.Printf类似 - `log.Println`:和fmt.Println类似 - `log.Print`:和fmt.Print类似 ```go package main import ( "log" ) func main() { var age = 22 log.Printf("I'm %d years old", age) str1 := "Hello world !" log.Println(str1) log.Print(str1) log.Printf("%s", str1) } ``` 执行结果: ```go 2021/08/12 16:52:12 I'm 22 years old 2021/08/12 16:52:12 Hello world ! 2021/08/12 16:52:12 Hello world ! 2021/08/12 16:52:12 Hello world ! ``` 下面来介绍一下go的数据类型 ## 数据类型 下表列出了go语言的数据类型: | 类型 | 说明 | 示例 | | :---------------- | :----------------------------------------------------------- | :------------------------------------ | | 布尔类型 bool | 可以是常量 true 或者 false | `var flag bool = true` | | 数字类型 | 有符号整型:int8、int16、int32、int64
无符号整型:uint8、uint16、uint32、uint64
int和uint的具体长度取决于CPU位数
浮点型:float32、float64
| `var num int = 2` | | 字符串类型 string | 是UTF-8 编码的字符序列,只能使用双引号("")或反引号(``)定义 | `var a = “test”` | | 数组 array | 数组类型是由**固定长度**的特定类型元素组成的序列,长度和容量相同 | `var myarr [5] int{1,2,3}` | | 切片 slice | 切片类型是一种动态数组,是可变长的,长度和容量可相同也可以不相同 | `var myslice = []int{1, 2, 3}` | | 结构体 struct | 结构体是多个任意类型的变量组合 | | | 字典 map | 存储键值对的集合 | `var mymap map[int]string` | | 通道 channel | 相当于一个先进先出(FIFO)的队列,可以利用通道在多个 goroutine 之间传递数据 | `ch := make(chan int, 3)` | | 接口 interface | 接口类型定义方法的集合,它无法实例化 | | | 函数 func | 函数类型是一种对一组输入、输出进行模板化的重要工具 | `type add func(a int, b int) (n int)` | | 指针 pointer | go语言的指针类型和C/C++中的指针类型类似,是指向某个确切的内存地址的值 | | int、float、bool、string、数组和struct属于值类型,这些类型的变量直接指向存在内存中的值;slice、map、chan、pointer等是引用类型,存储的是一个地址,这个地址存储最终的值。 ## 常量声明 常量是在程序编译时就确定下来的值,程序运行时无法改变。 ```go package main import ( "fmt" ) func main() { const name string = "zhangsan" fmt.Println(name) const course1, course2 = "math", "english" fmt.Println(course1, course2) const age = 20 age = age + 1 // 不能改变age fmt.Println(age) } ``` 执行结果: ```go # command-line-arguments .\test_const.go:15:6: cannot assign to age (declared const) ``` ## 变量声明 go的变量声明主要包括三种方法: - 变量声明可指定变量类型,如果没有初始化,则变量默认为零值。 - 也可以不指定数据类型,由go自己判断。 - var可以省略,使用`:=`进行声明。注意:`:=` 左边的变量必须是没有声明新的变量,否则会编译错误。 ```go package main import ( "fmt" ) func main() { var name string = "zhangsan" fmt.Println(name) var hight float32 fmt.Println(hight) var course1, course2 = "math", "english" fmt.Println(course1, course2) age := 20 age = age + 1 fmt.Println(age) var ( name1 string = "zhangsan" name2 string = "lishi" ) fmt.Println(name1, name2) } ``` 执行结果: ```go zhangsan 0 math english 21 zhangsan lishi ``` ## 运算符 Go 语言的运算符主要包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符以及指针相关运算符。 算术运算符: | 运算符 | 说明 | | :----- | :--- | | + | 加 | | - | 减 | | * | 乘 | | / | 除 | | % | 求余 | | ++ | 自增 | | -- | 自减 | 关系运算符: | 运算符 | 说明 | | :----- | :--------- | | == | 是否相等 | | != | 是否不相等 | | > | 大于 | | < | 小于 | | >= | 大于等于 | | <= | 小于等于 | 逻辑运算符: | 运算符 | 说明 | | :----- | :------- | | && | 逻辑 AND | | \|\| | 逻辑 OR | | ! | 逻辑 NOT | 位运算符: | 运算符 | 说明 | | :----- | :----------------------------- | | & | 按位与,两个数对应的二进位相与 | | \| | 按位或 | | ^ | 按位异或 | | << | 左移,左移n位表示乘以2的n次方 | | >> | 右移,右移n位表示除以2的n次方 | 赋值运算符: | 运算符 | 说明 | | :----- | :------------- | | = | 简单赋值运算符 | | += | 相加后再赋值 | | -= | 相减后再赋值 | | *= | 相乘后再赋值 | | /= | 相除后再赋值 | | %= | 求余后再赋值 | | <<= | 左移后赋值 | | >>= | 右移后赋值 | | &= | 按位与后赋值 | | ^= | 按位异或后赋值 | | \|= | 按位或后赋值 | 指针相关运算符: | 运算符 | 说明 | | :----- | :----------------------------------------------------------- | | & | 返回变量在内存中的地址 | | * | 如果`*`后面是指针,表示取指针指向的值;如果`*`后面是类型,则表示一个指向该类型的指针。 | ## 条件语句 下面介绍一下go语言中的if语句和switch语句。另外还有一种控制语句叫select语句,通常与通道联用,这里不做介绍。 ### if语句 if语法格式如下: ```go if [布尔表达式] { // do something } ``` if ... else : ```go if [布尔表达式] { // do something } else { // do something } ``` else if: ```go if [布尔表达式] { // do something } else if [布尔表达式] { // do something } else { // do something } ``` 示例代码: ```go package main import "fmt" func main() { var grade = 70 if grade >= 90 { fmt.Println("A" ) } else if grade < 90 && grade >= 80 { fmt.Println("B" ) } else if grade < 80 && grade > 60 { fmt.Println("C" ) } else { fmt.Println("D" ) } } ``` ### switch 语句 语法格式: ```go switch var1 { case cond1: // do something case cond2: // do something default: // do something:条件都不满足时执行 } ``` 另外,添加 fallthrough 会强制执行后面的 case 语句,不管下一条case语句是否为true。 示例代码: ```go package main import "fmt" func main() { var grade = "B" switch grade { case "A": fmt.Println("优秀") case "B": fmt.Println("良好") fallthrough case "C": fmt.Println("中等") default: fmt.Println("不及格") } } ``` 执行结果: ```go 良好 中等 ``` ## 循环语句 下面介绍几种循环语句: ### for循环:使用分号 ```go package main import "fmt" func main() { sum := 0 for i := 1; i < 5; i++ { sum += i } fmt.Println(sum) // 10 (1+2+3+4) } ``` ### 实现while效果 ```go package main import "fmt" func main() { sum := 0 n := 0 for n < 5 { sum += n n += 1 } fmt.Println(sum) // 10 (1+2+3+4) } ``` ### 死循环 ```go package main import "fmt" func main() { sum := 0 for { sum++ } fmt.Println(sum) } ``` ### for range 遍历 ```go package main import "fmt" func main() { strings := []string{"hello", "world"} for index, str := range strings { fmt.Println(index, str) } } ``` 执行结果: ```go 0 hello 1 world ``` ### 退出循环 - continue:结束当前迭代,进入下一次迭代 - break:结束当前for循环 ```go package main import "fmt" func main() { sum := 0 for { sum++ if sum%2 != 0 { fmt.Println(sum) continue } if sum >= 10 { break } } fmt.Println(sum) } ``` 执行结果: ```go 1 3 5 7 9 10 ``` 也可以通过标记退出循环: ```go package main import "fmt" func main() { sum := 0 n := 0 LOOP: for n <= 10 { if n == 8 { break LOOP } sum += n n++ } fmt.Println(sum) // 28 (0+1+2+3+4+5+6+7) } ``` ### goto语句 ```go package main import "fmt" func main() { sum := 0 sum2 := 0 n := 0 LOOP: for n <= 10 { if n%2 == 0 { sum += n n++ goto LOOP } sum2 += n n++ } fmt.Println(sum) // 30 (0+2+4+6+8+10) fmt.Println(sum2) // 25 (1+3+5+7+9) } ```