Golang准备
学习方向:
![image-20220125154146099](https://gitee.com/jtyyds/drawing-bed/raw/master//image-20220125154146099.png)
![image-20220125154239706](https://gitee.com/jtyyds/drawing-bed/raw/master//image-20220125154239706.png)
Go语言的特点:
Go语言保证了既能达到静态编译语言的安全和性能,又达到了动态语言开发维护的高效率,使用一个表达式来形容Go语言,Go=C + Python,说明Go语言既有C静态语言程序的运行速度,又能达到Python动态语言的快速开发。
1.从c语言中继承了很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等等,也保留了和c语言一样的编译执行方式及弱化的指针。
2.引入包的概念,用于组织程序结构,Go语言的一个文件都要归属于一个包,而不能单独存在。
3.垃圾回收机制,内存自动回收,不需要开发人员管理。
4.天然并发
(1)从语言层面支持并发实现简单
(2)goroutine,轻量级线程,可实现大并发处理,高效利用多核。
(3)基于CSP并发模型(Comminicating Sequential Processes)实现。
5.吸收管道通信机制,形成Go语言特有的管道channel通过管道channel,可以实现不同的goroute之间的相互通信。
6.函数返回多个值。
7.新的创新:比如切片slice、延时执行defer等。
环境配置:
![image-20220125154411789](https://gitee.com/jtyyds/drawing-bed/raw/master//image-20220125154411789.png)
![image-20220125154426426](https://gitee.com/jtyyds/drawing-bed/raw/master//image-20220125154426426.png)
![image-20220125154444457](https://gitee.com/jtyyds/drawing-bed/raw/master//image-20220125154444457.png)
GoLand和VSCode安装
![img](https://gitee.com/jtyyds/drawing-bed/raw/master//DB1B58B1EE44B8519B2617718D21697B.png)
Golang入门
go的目录结构
![image-20220116173219377](https://gitee.com/jtyyds/drawing-bed/raw/master/phones/image-20220116173219377.png)
hello world
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
-
go文件的后缀是 .go
-
package main 表示该 hello.go 文件所在的包是main,在go中,每个文件都必须归属一个包。
-
import “fmt” 表示引入一个包,包名fmt,引入该包后,就可以使用fmt包的函数,比如:fmt.Println
-
func main(){} func 是一个关键字,表示一个函数。main是函数名,是一个主函数,即我们程序的入口。
-
fmt.Println(“hello world”) 表示调用fmt包的函数Println输出"hello world"
通过go build + 文件名 编译文件
生成.exe 可执行文件
go run + 文件名
直接运行
linux下的Go程序
linux下开发go和windows开发基本一样。只是在运行可以执行的程序时,是以 ./文件名方式
Golang执行流程的分析
![image-20220116175634456](https://gitee.com/jtyyds/drawing-bed/raw/master/phones/image-20220116175634456.png)
两种执行流程的方式区别
1.如果我们先编译生成了可执行文件,那么我们可以将可执行文件拷贝到没有go开发环境的机器上,任然可以执行。
2.如果我是直接go run go源代码,那么如果要在另一个机器上运行,也想要go开发环境,否则无法执行。
3.在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所有可执行文件变大了很多。
![image-20220116180525327](https://gitee.com/jtyyds/drawing-bed/raw/master/phones/image-20220116180525327.png)
编译和运行
自主命名:
go build -o 生成文件名.exe 源文件.go
![image-20220116190945380](https://gitee.com/jtyyds/drawing-bed/raw/master/phones/image-20220116190945380.png)
注意事项
![image-20220116192343988](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220116192343988.png)
1.Go源文件以“go”为扩展名
2.Go应用程序的执行入口是main()函数。
3.Go语言是严格区分大小写的。
4.Go方法由一条条语句构成,每个语句后不需要分号(Go语言会在没行后自动加分号),这也体现出了Golang的简洁性。
5.Go编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一行,否则会报错。
6.Go语言定义的变量或者import包如果没有使用到,代码不能编译通过。
7.大括号都是成对出现的,缺一不可。
GO语言常用的转义字符
和c语言类似
转义字符: |
---|
\n (换行) |
\t (表示一个制表符,通常使用它可以排版) |
\ (转义) |
\r (回车,表示从当前行的最前面开始输出,覆盖掉以前内容) |
Go语言注释
行注释: //
块注释: /**/
规范的代码风格
正确的注释和注释风格
Go官方推荐使用行注释
正确的缩进和空白
1.使用一次tab操作,实现缩进,默认整体向右移动,有时候shift+tab整体向左移动。
2.或使用gofmt来进行格式化
3.运算符两边习惯性各加一个空格。
4.大括号的写法
![image-20220116202042185](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220116202042185.png)
5.换行用逗号(,)
![image-20220116202625450](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220116202625450.png)
变量
变量是程序的基本组成单位
概念:
变量相当于内存中一个数据存储空间的表示,通过变量名可以访问到变量值。
声明变量:
var 变量名 数据类型
package main
import "fmt"
func main() {
var i int = 10
fmt.Println(i)
}
使用的注意事项
1.变量表示内存中的一个存储区域
2.该区域有自己的名称(变量名)和类型(数据类型)
3.Golang变量使用的三种方式
(1)指定变量类型,声明后若不赋值,使用默认值
(2)根据值自行判定变量类型(类型推导)
(3)省略var,注意:=左侧的变量不应该事故已声明过的,否则会导致编译错误
4.多变量声明,在编译值,有时候我们需要一次性声明多个变量,Golang也提供这样的语法。
5.该区域的数据值可以在同一类型范围内不断变化
6.变量在同一个作用域内不能重名
7变量=变量名+值+数据类型
8.Golang的变量如果没有赋初值,会赋一个默认值。
package main
import "fmt"
var n7 = 100
var n8 = 200
var name2 = "jt"
//一次声明
var (
n9 = 100
n10 = 200
name3 = "jt"
)
func main() {
//golang的变量使用方式1
//第一种:指定变量类型,声明后若不赋值,使用默认值// int的默认值是e,其它数据类型的默认值后面马上介绍var i int
var i int
fmt.Println("i =", i)
//第二种:根据值自行判定变量类型(类型推导)var num =10.11
var num = 10.11
fmt.Println("num =", num)
//第三种:省略var,注意:=左侧的变量不应该是已经声明过的,香则会导致编译错误1/下面的方式等价var name stringname = "tom"
// :=的:不能省略,否则错误
name := "tom"
fmt.Println("name =", name)
//该案例演示golang如何一次性声明多个变量
var n1, n2, n3 int
fmt.Println(n1, n2, n3)
// 一次性声明多个变量的方式2
var n5, name1, n4 = 108, "tom", 888
fmt.Println(n5, name1, n4)
//一次性声明多个变量的方式3,同样可以使用类型推导
n5, name1, n4 = 108, "tom", 888
fmt.Println(n5, name1, n4)
//输出全局变量
fmt.Println(n7, name2, n8)
fmt.Println(n9, name3, n10)
}
+号的使用
1.当左右两边都是数值型时,则做加法运算
2.当左右两边都是字符串,则做字符串拼接
package main
import "fmt"
//+ 号的使用
func main() {
var i = 1
var j = 2
var r = i + j
fmt.Println(r)
var str1 = "hello"
var str2 = "world"
var str = str1 + str2
fmt.Println(str)
}
数据类型
整数类型
类型 | 有无符号 | 占用存储空间 | 数据范围 |
---|---|---|---|
int8 | 有 | 1字节 | -128 ~ 127 |
int16 | 有 | 2字节 | -215 ~ 215-1 |
int32 | 有 | 4字节 | -231 ~ 231-1 |
int64 | 有 | 8字节 | -263 ~ 263-1 |
uint8 | 无 | 1字节 | 0 ~ 255 |
uint16 | 无 | 2字节 | 0 ~ 216-1 |
uint32 | 无 | 4字节 | 0 ~ 232-1 |
uint64 | 无 | 8字节 | 0 ~ 264-1 |
类型 | 有无符号 | 数据范围 | 备注 |
---|---|---|---|
int | 有 | -231 ~ 231-1,-263~263-1 | |
uint | 无 | 0 ~ 232-1,0 ~ 264-1 | |
rune | 有 | -231 ~ 231-1 | 等价int32,表示一个Unicode码 |
byte | 无 | 0 ~ 255 | 当要存储字符是选用byte |
1.Golang各整数类型分:有符号和无符号,int uint的大小和系统有关。
2.Golang的整型默认声明为int型
fmt.Printf("a 的类型 %T", a)//输出数据类型
3.如何在程序查看某个变量的字节大小和数据类型
fmt.Printf("a 的类型 %T a 占用的字节数是 %d", a, unsafe.Sizeof(a))//输出字节大小
4.Golang程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型。
5.bit:计算机中的最小存储单位。byte:计算机中基本存储单元。1byte = 8 bit
浮点类型
类型 | 占用存储空间 | 表数范围 |
---|---|---|
单精度float32 | 4字节 | -3.403E38 ~ 3.403E38 |
双精度float64 | 8字节 | -1.798E308~ 1.798E308 |
说明一下:
1)关于浮点数在机器中存放形式的简单说明,浮点数=管号拉+指数位+尾数位3.56
11110000111.111111111111111111000
2)尾数部分可能丢失,造成精度损失。-123.0000901
//尾数部分可能丢失,造成精度损失。
var num3 float32 = -123.0000901
var num4 float64 = -123.0000901
fmt.Println("num3=", num3, "num4=", num4)
3)浮点型的存储分为三部分:符号位+指数位+尾数位在存储过程中,精度会有丢失
浮点型使用细节
- Golang浮点类型有固定的范围和字段长度,不受具体oSI操作系统)的影响。
- Golang 的浮点型默认声明为float64类型。
- 浮点型常量有两种表示形式,十进制数形式:如:5.12 .512(必须有小数点),科学计数法形式:如:5.1234e2 = 5.12*10的2次方 , 5.12E-2 =5.12/10的2次方
- 通常情况下,应该使用float64,因为它比float32更精确。
字符类型
Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的。
var c1 byte = 'a'
var c2 byte = '0' //字符的0
//当我们直接输出byte值,就是输出了的对应的字符的码值// "a' ==>
fmt.Println("c1=", c1)
fmt.Println("c2=", c2)
//如果我们希望输出对应字符,需要使用格式化输出
fmt.Printf("c1=%c c2=%c\n", c1, c2)
//var c3 byte =‘北’//overflow溢出
var c3 int = '北' //overflow溢出
fmt.Printf("c3=%c c3对应码值=%d", c3, c3)
字符类型使用细节
1.字符常量是用单引号(’’)括起来的单个字符。例如: var c1 byte = ‘a’ , var c2 int=“中” var c3 byte = ‘9’
2.Go中允许使用转义字符尘来将其后的字符转变为特殊字符型常量。例如: var c3 char = ‘\n’ // \n表示换行符
3.Go语言的字符使用UTF-8编码,英文字母是1个字节,汉字是3个字节
4.在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值。
5.可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的unicode字符
6.字符类型是可以进行运算的,相当于一个整数,因为它都
对应有Unicode码.
字符类型本质探讨
-
1.字符型存储到计算机中,需要将字符对应的码值(整数)找出来
存储:字符->对应码值---->二进制–>存储
读取:二进制---->码值----->字符–>读取
-
2.字符和码值的对应关系是通过字符编码表决定的(是规定好)
-
3.Go语言的编码都统一成了utf-8。非常的方便,很统一,再也没有编码乱码的困扰了
布尔类型:bool
- 布尔类型也叫bool类型,bool类型数据只允许取值true和false
-
bool类型占1个字节。
-
bool类型适于逻辑运算,一般用于程序流程控制
布尔使用细节
不可用0或非0的整数代替false和true
字符串数据类型:string
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本
字符串使用细节
-
Go语言的字符串的字节使用uTF-8编码标识unicode文本,这样Golang统一使用UTF-8编码,中文乱码问题不会再困扰程序员。
-
字符串一旦赋值了,字符串就不能修改了﹔在Go中字符串是不可变的。
-
字符串的两种表示形式
1)双引号,会识别转义字符
2)反引号(``),以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
-
字符串拼接方式(+)
-
当一个拼接的操作很长时,怎么办,可以分行写,但是注意,需要将+保留在上一行.
数据类型的默认值
在go中,数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值,在go中,默认值又叫零值。
数据类型 | 默认值 |
---|---|
整数 | 0 |
浮点型 | 0 |
字符串 | “” |
布尔类型 | false |
基本类型的转换
Golang 和java / c不同,Go在不同类型的变量之间赋值时需要显式转换。也就是说Golang中数据类型不能自动转换。
转换语法
表达式T(v)将值v转换为类型T
T:就是数据类型,比如int32,int64,float32等等
v:就是需要转换的变量
细节:
- Go中,数据类型的转换可以是从表示范围小–>表示范围大,也可以范围大—>范围小
- 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化!
- 在转换中,比如将int64 转成int8,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。
练习:
var n1 int32 = 12
var n3 int8
var n4 int8
n4 = int8(n1) + 127 //编译通过,会出现溢出
n3 = int8(n1) + 128 //编译不过
fmt.Println(n3)
基本数据类型和string的转换
基本数据类型转string
方式一: fmt.Sprintf("%参数",表达式)
package main
import "fmt"
func main() {
var num1 int = 99
var num2 float32 = 21.11
var b bool = true
var mychar byte = 'h'
var str string //空的str
//使用第一种方式转换 fmt.Sprintf方法
str = fmt.Sprintf("%d", num1)
fmt.Printf("%T,%q\n", str, str)
str = fmt.Sprintf("%f", num2)
fmt.Printf("%T,%q\n", str, str)
str = fmt.Sprintf("%t", b)
fmt.Printf("%T,%q\n", str, str)
str = fmt.Sprintf("%c", mychar)
fmt.Printf("%T,%q", str, str)
}
方式二:使用strconv包的函数
//第二种方式
var num3 int = 99
var num4 float64 = 21.11
var b2 bool = true
str = strconv.FormatInt(int64(num3), 10)
fmt.Printf("%T,%q\n", str, str)
str = strconv.FormatFloat(num4, 'f', 10, 64)
fmt.Printf("%T,%q\n", str, str)
str = strconv.FormatBool(b2)
fmt.Printf("%T,%q\n", str, str)
//strconv包中有一个函数Itoa
var num5 int = 456
str = strconv.Itoa(num5)
fmt.Printf("%T,%q\n", str, str)
string转基本数据类型
1.使用strconvh包的函数
package main
import (
"fmt"
"strconv"
)
func main() {
var str string = "true"
var b bool
b, _ = strconv.ParseBool(str)
fmt.Printf("%T %v", b, b)
var str2 string = "12315"
var n1 int64
n1, _ = strconv.ParseInt(str2, 10, 64)
fmt.Printf("%T %v", n1, n1)
var str3 string = "213.454"
var f1 float64
f1, _ = strconv.ParseFloat(str3, 64)
fmt.Printf("%T %v", f1, f1)
}
注意事项
在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据,比如我们可以把"123”,转成一个整数,但是不能把"hello”转成一个整数,如果这样做,Golang直接将其转成0
指针
1.基本数据类型,变量存的就是值,也叫值类型
2.获取变量的地址,用&,比如:var num int,获取num的地址:&num
3.指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值比如: var ptr *int = &num
4.获取指针类型所指向的值,使用:,比如:var ptr * int,使用ptr获取ptr指向的值
![image-20220118210029416](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220118210029416.png)
指针使用细节
1.值类型,都有对应的指针类型,形式为*数据类型,比如int的对应的指针就是 * int, float32对应的指针类型就是 *float32,依次类推。
2.值类型包括:基本数据类型int系列, float系列, bool, string、数组和结构体struct
值类型和应用类型
值类型:基本数据类型 int系列, float系列, bool, string 、数组和结构体struct
引用类型。指针、slice切片、map、管道chan、 interface等都是引用类型
![image-20220118211825535](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220118211825535.png)
标识符
概念
- Golang对各种变量、方法、函数等命名时使用的字符序列称为标识符
- 凡是自己可以起名字的地方都叫标识符
标识符的命名规则
- 由26个英文字母大小写,0-9 ,_组成
- 数字不可以开头。
- Golang中严格区分大小写。
- 标识符不能包含空格。
- 下划线"_"本身在Go中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用。
- 不能以系统保留关键字作为标识符,比知break,if等等…
保留关键字
![image-20220119113005676](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119113005676.png)
标识符注意事项
- 包名,保持package的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库不要冲突
- 变量名、函数名、常量名:采用驼峰法。
- 如果变量名、函数名、常量名首字母大写,则可以被其他的包访间;如果首字母小写,则只能在本包中使用(注:可以简单的理解成,首字母大写是公有的,首字母小写是私有的)---->从src后的包开始引用
![image-20220119114859478](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119114859478.png)
预定义标识符
![image-20220119115233289](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119115233289.png)
运算符
运算符是—种特殊的符号,用以表示数据的运算、赋值和比较等
- 算术运算符
- 赋值运算符
- 比较运算符
- 逻辑运算符
- 位运算符
- 其它运算符
算术运算符
算术运算符是对数值类型的变量进行运算的,比如:加减乘除。在Go程序中使用的非常多。
![image-20220119120007731](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119120007731.png)
注意:
i++只能独立使用
Golang 的4+和–只能写在变量的后面,不能写在变量的前面,即,只有 a++ a–没有++a
关系运算符(比较运算符)
- 关系运算符的结果都是bool型,也就是要么是true,要么是false
- 关系表达式经常用在if结构的条件中或循环结构的条件中
![image-20220119150806839](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119150806839.png)
逻辑运算符
用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个bool值。
![image-20220119151849684](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119151849684.png)
注意:
&&也叫短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false
||也叫短路或。如果第一个条件为true,则第二个条件不会判断,最终结果为true
赋值运算符
赋值运算符就是将某个运算后的值,赋给指定的变量。
![image-20220119155845184](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119155845184.png)
运算符的优先级
![image-20220119163017908](https://gitee.com/jtyyds/drawing-bed/raw/master/phones3/image-20220119163017908.png)
位运算符
![image-20220119163303535](https://gitee.com/jtyyds/drawing-bed/raw/master/phones2/image-20220119163303535.png)
其他运算符
![image-20220119163527935](https://gitee.com/jtyyds/drawing-bed/raw/master/phones2/image-20220119163527935.png)
原码,反码,补码
1)二进制的最高位是符号位:0表示正数,1表示负数
1 ==>[0000 0001]
-1=>[1000 0001]
2)正数的原码,反码,补码都一样
3)负数的反码=它的原码符号位不变,其它位取反(0->1,1->0)
1=>原码[0000 0001]反码[0000 0001]补码[0000 0001]
-1=>原码[1000 0001]反码[11111110]补码[1111 1111]
4)负数的补码=它的反码+1
5)0的反码,补码都是0
6)在计算机运算的时候,都是以补码的方式来运算的.1-1=1+(-1)
![image-20220119174337779](https://gitee.com/jtyyds/drawing-bed/raw/master/phones5/image-20220119174337779.png)
Golang不支持三元运算
键盘输入语句
步骤:
1)导入fmt包
2)调用fmt包的fmt.Scanln()或者fmt.Scanf()
package main
import "fmt"
func main() {
//方式一:fmt.Scanln
var name string
var age byte
var sal float32
var isPass bool
fmt.Println("请输入姓名")
fmt.Scanln(&name)
fmt.Println("请输入年龄")
fmt.Scanln(&age)
fmt.Println("请输入薪水")
fmt.Scanln(&sal)
fmt.Println("请输入是否通过考试")
fmt.Scanln(&isPass)
fmt.Println(name, age, sal, isPass)
//方式二:fmt.Scanf
fmt.Printf("请输入你的名字,年龄,薪水,是否通过考试,使用空格隔开")
fmt.Scanf("%s %d %f %t", &name, &age, &sal, &isPass)
fmt.Println(name, age, sal, isPass)
}
流程控制
- 顺序控制
- 分支控制
- 循环控制
顺序控制
程序顺序执行
if分支控制
- 单分支(if)
- 双分支(if—else)
- 多分支(if----if else—else)
- 嵌套分支(建议控制在三层内)
注意格式是固定的与其他语言不同
package main
import "fmt"
func main() {
var i int = 10
if i > 10 {
fmt.Printf("i>10")
} else if i > 20 {
fmt.Printf("i>20")
} else {
fmt.Printf("其他")
}
}
switch分支结构
switch语句用于基于不同条件执行不同动作,每一个case分支都是唯一的,从上到下逐一测试,直到匹配为止。
golang的case后的表达式可以有多个,使用逗号间隔
匹配项后面也不需要再加break
golang 中的case 语句块不需要写break,因为默认会有,即在默认情况下,当程序执行完case语句块后,就直接退出该switch控制结构。
package main
import "fmt"
func main() {
var key byte
fmt.Scanf("%c", &key)
switch key {
case 'a':
fmt.Println("你输入了a")
case 'b':
fmt.Println("你输入了b")
default:
fmt.Println("输入错误")
}
}
switch细节
-
case后是一个表达式(即:常量值、变量、一个有返回值的函数狰都可以)
-
case后的各个表达式的值的数据类型,必须和 switch 的表达式数据类型一致
-
case后面可以带多个表达式,使用逗号间隔。比如case表达式1,表达式2…
-
case后面的表达式如果是常量值(字面量),则要求不能重复
-
case后面不需要带break ,程序匹配到一个case后就会执行对应的代码块,然后退出switch,如果一个都匹配不到,则执行default
-
default语句不是必须的.
-
switch后也可以不带表达式,类似if --else分支来使用。
![image-20220120164538029](https://gitee.com/jtyyds/drawing-bed/raw/master/phones5/image-20220120164538029.png)
- switch 后也可以直接声明定义一个变量,分号结束,不推荐。
![image-20220120164729257](https://gitee.com/jtyyds/drawing-bed/raw/master/phones5/image-20220120164729257.png)
-
switch穿透-fallthrough ,如果在case语句块后增加fallthrough ,则会继续执行下一个case,也叫switch穿透。
-
Type Switch: switch 语句还可以被用于type-switch来判断某个interface变量中实际指向的变量类型
for循环控制
![image-20220120204445955](https://gitee.com/jtyyds/drawing-bed/raw/master/phones4/image-20220120204445955.png)
示例:
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
fmt.Println("hello word!")
}
}
package main
import "fmt"
func main() {
i := 0
for i < 10 {
fmt.Println("hello word!")
i++
}
}
package main
import "fmt"
func main() {
i := 0
for {
fmt.Println("hello word!")
i++
if i >= 10 {
break
}
}
}
Golang 提供for-range的方式,可以方便遍历字符串和数组,案例说明如何遍历字符串。
package main
import "fmt"
func main() {
//方式1:
var str string = "hello world"
for i := 0; i < len(str); i++ {
fmt.Printf("%c\n", str[i])
}
//for-range遍历
str = "asdccc"
for index, val := range str {
fmt.Printf("index=%d,var=%c\n", index, val)
}
}
如果字符串含有中文,传统的对字符串的遍历是按字节遍历的,一个汉字对应三个字节,需要将str 转换为 []rune 切片,对于for-range是按照字符方式编译,有中文不会影响
package main
import "fmt"
func main() {
var str string = "hello 江涛"
str2 := []rune(str)
for i := 0; i < len(str2); i++ {
fmt.Printf("%c\n", str2[i])
}
}
Go语言没有while和do…while
多重循环控制
![image-20220125212534052](https://gitee.com/jtyyds/drawing-bed/raw/master/phones4/image-20220125212534052.png)
跳转控制语句-break
随机数生成:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
//生成1-100的随机数
//设置rand的一个种子
rand.Seed(time.Now().Unix()) //返回一个从1970:01:01的0时0分0秒到现在的秒数
n := rand.Intn(100) + 1
fmt.Println(n)
//随机生成1-100的一个数,直到生成了99这个数,看看你一共用了几次
var count int = 0
for {
rand.Seed(time.Now().UnixNano())
n := rand.Intn(100) + 1
fmt.Println(n)
count++
if n == 99 {
break
}
}
fmt.Println(count)
}
注意事项:
break默认跳出最近的for循环
break配合标签使用
![image-20220120220341135](https://gitee.com/jtyyds/drawing-bed/raw/master/phones5/image-20220120220341135.png)
label1:
for {
rand.Seed(time.Now().UnixNano())
n := rand.Intn(1000) + 1
fmt.Println(n)
count++
if n == 999 {
break label1
}
}
跳转控制语句-continue
![image-20220120221326879](https://gitee.com/jtyyds/drawing-bed/raw/master/phones5/image-20220120221326879.png)
跳转控制语句-goto
![image-20220120221843344](https://gitee.com/jtyyds/drawing-bed/raw/master/phones5/image-20220120221843344.png)
package main
import "fmt"
func main() {
//goto的使用
fmt.Println("1")
fmt.Println("2")
goto label1
fmt.Println("3")
fmt.Println("4")
fmt.Println("5")
label1:
fmt.Println("6")
fmt.Println("7")
}
跳转控制语句-return
return跳出函数