1、if条件判断写法
package main
import "fmt"
func main() {
/*
if 表达式1 {
分支1
}else if 表达式2{
分支2
}else {
分支3
}
*/
flag := true
if flag {
fmt.Println("flag=true")
}
age := 30 //当前作用域的全局变量
if age > 20 {
fmt.Println("age>20")
}
if len := 34; len > 50 { //if作用域内的局部变量
fmt.Println("len>50")
} else if len > 40 {
fmt.Println("len>40")
} else {
fmt.Println("else")
}
}
2、for(循环结构)
for循环格式: for 初始语句;条件表达式;结束语句{ 循环体语句 }
package main
import "fmt"
func main() {
//打印1到10,先执行i:=1,在执行条件表达式i <= 10;再执行循环体;在执行结束语句,再条件判断,后面依次运行。
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
i := 1
for i <= 10 {
fmt.Println(i)
i++
}
i = 1
for ; i <= 10; i++ {
fmt.Println(i)
}
}
for无限循环,golang没有while语句可以使用for代替while,通过break\goto\return\panic语句强制退出循环。
package main
import "fmt"
func main() {
i := 1
for {
if i <= 10 {
fmt.Println(i)
} else {
break
}
i++
}
}
for嵌套
package main
import "fmt"
func main() {
var row = 5
var column = 8
for i := 0; i < row; i++ {
for j := 0; j < column; j++ {
fmt.Print("*")
}
fmt.Println("")
}
}
1、for range遍历数据
package main
import "fmt"
func main() {
str := "你好go"
//for range遍历字符串字符
for k, v := range str {
fmt.Println("key=", k, "value=", v)
fmt.Printf("key=%v value=%c\n", k, v)
}
//for range遍历字符串切片
var arr = []string{"php", "java", "node", "python"}
for k, v := range arr {
fmt.Printf("key=%v value=%v\n", k, v)
}
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
}
2、switch case,对大量的值进行条件判断;go语言规定每个switch只能有一个default分支。break可以省略。
package main
import "fmt"
func main() {
var ext = ".txt"
switch ext {
case ".exe":
fmt.Println("exe")
break
case ".txt":
fmt.Println("txt")
break
case ".py":
fmt.Println("py")
break
default:
fmt.Println("not find")
}
}
3、switch 的穿透 fallthrought,fallthrought语法可以执行满足条件的case的下一个case,是为了兼容C语言中的case设计。
package main
import "fmt"
func main() {
var ext = ".txt"
switch ext {
case ".exe":
fmt.Println("exe")
case ".txt":
fmt.Println("txt")
fallthrough
case ".py":
fmt.Println("py")
default:
fmt.Println("not find")
}
}
1、continue
package main
import "fmt"
func main() {
for i := 1; i <= 10; i++ {
if i == 2 {
//continue 结束本次循环,开始下次循环
continue
}
fmt.Println(i)
}
label2:
for i := 0; i < 2; i++ {
for j := 0; j < 10; j++ {
if j == 3 {
continue label2
}
fmt.Printf("i=%v j=%v\n", i, j)
}
}
}
2、break
package main
import "fmt"
func main() {
for i := 1; i <= 10; i++ {
if i == 2 {
break
}
fmt.Println(i)
}
var ext = ".txt"
switch ext {
case ".exe":
fmt.Println("exe")
break
case ".txt":
fmt.Println("txt")
break
case ".py":
fmt.Println("py")
break
default:
fmt.Println("not find")
}
// 在多重循环中,可以用label 标出想跳出的循环
label1:
for i := 0; i < 2; i++ {
for j := 0; j < 10; j++ {
if j == 3 {
break label1
}
fmt.Printf("i=%v j=%v\n", i, j)
}
}
}
3、goto, goto用于代码间的无条件跳转。
package main
import "fmt"
func main() {
n := 30
if n > 24 {
fmt.Println("n>24")
goto lable3
}
fmt.Println("aaa")
lable3:
fmt.Println("bbb")
}
1、Array(数组)的介绍 数组的长度是类型的一部分,数组长度固定(切片slice可以增长和收缩)。
2、数组定义(数组的长度是类型的一部分)
var 数组变量名 [元素数量]T 例子: var a [3]int
3、数组的初始化、数组的遍历(for或for range)
package main
import "fmt"
func main() {
//数组的长度是类型的一部分
var arr1 [3]int
var arr2 [4]int
var strArr [3]string
fmt.Printf("%T %T %T", arr1, arr2, strArr)
//初始化
fmt.Println(arr1)
fmt.Println(strArr)
arr1[0] = 1
arr1[1] = 20
arr1[2] = 33
fmt.Println(arr1)
//声明并赋值
var arr3 = [3]int{1, 2, 3}
fmt.Println(arr3)
//让编译器根据初始化值的个数推断数组长度
var numArr = [...]int{1, 2, 3, 4}
//改变数组的值
numArr[0] = 2
fmt.Println(numArr)
fmt.Println(len(numArr))
//指定索引值的方式初始化数组
a := [...]int{1: 1, 5: 5}
fmt.Println(a)
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
for k, v := range numArr {
fmt.Println(k, v)
}
}
1、多维数组
var 数组变量名 [元素数量][元素数量]T var variable_name [size1][size2]...[sizen]variable_type
package main
import "fmt"
func main() {
//一维数组
//var arr1 = [3]int{1, 2, 3}
var arr2 = [3][2]string{
{"北京", "上海"},
{"广州", "重庆"},
{"四川", "成都"},
}
fmt.Println(arr2[0][1])
for _, v1 := range arr2 {
for _, v2 := range v1 {
fmt.Println(v2)
}
}
}
2、值类型 引用类型详解.值类型:当改变一个变量副本时不会改变变量本身。引用类型:改变副本的值,本身也改变。
package main
import "fmt"
func main() {
//值类型 引用类型
//基本类型和数组都是值类型
var a = 10
b := a
a = 20
fmt.Println(a, b)
var arr1 = [...]int{1, 2, 3}
arr2 := arr1
arr1[0] = 111
fmt.Println(arr1, arr2)
//切片是引用类型
var arr3 = []int{1, 2, 3}
arr4 := arr3
arr3[0] = 1123
fmt.Println(arr3, arr4)
}
切片的定义: 切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。灵活,支持自动扩容。切片是一个引用类型,它的内部结构包含地址、长度和容量。
声明语法:name表示变量名,T表示切片中的元素类型。
var name []T
只声明不赋值,会设置默认零值
类型 | 默认零值 |
---|---|
bool | false |
bunbers | 0 |
string | "" |
pointers | nil |
maps | nil |
channels | nil |
functions | nil |
package main
import "fmt"
func main() {
//声明切片
var arr1 []int
//打印切片的值,类型,长度
fmt.Printf("%v - %T - 长度: %v \n", arr1, arr1, len(arr1))
fmt.Println(arr1 == nil) // 默认值nil
//声明方法二
var arr2 = []int{1, 2, 3, 4}
fmt.Printf("%v - %T - 长度: %v \n", arr2, arr2, len(arr2))
//声明方法三,指定索引值
var arr3 = []int{1: 1, 3: 2, 4: 3, 6: 4}
fmt.Printf("%v - %T - 长度: %v \n", arr3, arr3, len(arr3))
}
切片的循环遍历
package main
import "fmt"
func main() {
var arr4 = []string{"golang", "python", "java", "php", "js"}
for i := 0; i < len(arr4); i++ {
fmt.Println(arr4[i])
}
for k, v := range arr4 {
fmt.Println(k, v)
}
}
基于数组定义切片和切片定义切片
package main
import "fmt"
func main() {
//基于数组定义切片
var arr4 = [5]string{"golang", "python", "java", "php", "js"}
a := arr4[:] //获取数组所有值
b := arr4[1:3] //获取索引1到3之前的,索引1和索引2
fmt.Printf("%v-%T;%v-%T", a, a, b, b)
//基于切片定义切片
var arr5 = []string{"golang", "python", "java", "php", "js"}
arr6 := arr5[:]
fmt.Printf("%v-%T", arr6, arr6)
}
切片的长度和容量,长度是包含元素的个数,切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。
package main
import "fmt"
func main() {
//基于数组定义切片
var arr4 = [5]string{"golang", "python", "java", "php", "js"}
fmt.Printf("%d-%d\n", len(arr4), cap(arr4)) // 长度6,容量6
arr5 := arr4[2:]
fmt.Printf("%d-%d\n", len(arr5), cap(arr5)) //长度3,容量3
arr6 := arr4[2:3]
fmt.Printf("%d-%d\n", len(arr6), cap(arr6)) //长度1,容量3
}
切片的本质是对底层数组的封装,它包含三个信息:底层数组的指针、切片长度(len)和切片容量(cap)
使用make()函数构造切片,make([]T,size, cap)
package main
import "fmt"
func main() {
//make函数创建切片
var sliceA = make([]int, 4, 7)
fmt.Printf("%v- %d - %d\n", sliceA, len(sliceA), cap(sliceA))
//修改切片里面的数据
sliceA[1] = 22
sliceA[2] = 40
fmt.Printf("%v\n", sliceA)
}
10、切片不能直接比较
append()方法为切片添加元素与切片的扩容策略
package main
import "fmt"
func main() {
var sliceA []int
//append追加数据
sliceA = append(sliceA, 11)
sliceA = append(sliceA, 22, 33, 44)
fmt.Printf("%v - %d - %d\n", sliceA, len(sliceA), cap(sliceA))
//append合并切片
var sliceB = []int{55, 66, 77}
sliceA = append(sliceA, sliceB...)
fmt.Printf("%v - %d - %d\n", sliceA, len(sliceA), cap(sliceA))
//切片扩容策略,小于1024容量翻倍
var sliceC []int
for i := 0; i < 10; i++ {
sliceC = append(sliceC, i)
fmt.Printf("%v - %d - %d\n", sliceC, len(sliceC), cap(sliceC))
}
}
使用copy()函数复制切片
package main
import "fmt"
func main() {
//引用类型,改变副本,原变量也改变
var sliceA = []int{55, 66, 77}
var sliceB = sliceA
sliceB[0] = 1024
fmt.Println(sliceA)
fmt.Println(sliceB)
// copy函数复制切片
var sliceC = []int{55, 66, 77}
var sliceD = make([]int, 3, 3)
copy(sliceD, sliceC)
sliceD[0] = 1024
fmt.Println(sliceC)
fmt.Println(sliceD)
}
从切片中删除元素
package main
import "fmt"
func main() {
//append删除元素
a := []int{1, 2, 3, 4, 5, 6, 7, 8}
//删除索引2的元素
a = append(a[:2], a[3:]...)
fmt.Println(a)
}
字符串修改,可以转换成byte或者rune类型切片
package main
import "fmt"
func main() {
s1 := "yellow"
byteStr := []byte(s1)
byteStr[0] = 'L'
fmt.Println(string(byteStr))
s2 := "尘光"
runeStr := []rune(s2)
runeStr[0] = '星'
fmt.Println(string(runeStr))
}
Golang内置Sort包对切片进行排序
map的介绍:是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。
map[KeyType]ValueType;KeyType表示键的类型,ValueType表示值的类型。默认初始值位nil,需要用make()函数来分配内存。
创建map
package main
import "fmt"
func main() {
// make创建map类型数据make(map[string]int,长度可以省略)
var userinfo = make(map[string]int)
userinfo["userid"] = 21
userinfo["age"] = 18
fmt.Println(userinfo, userinfo["userid"])
// 声明时填充数据
var userinfo2 = map[string]string{
"username": "zhangsan",
"age": "20",
"sex": "男",
}
fmt.Println(userinfo2, userinfo2["sex"])
}
map的遍历,for range循环遍历
package main
import "fmt"
func main() {
// make创建map类型数据make(map[string]int,长度可以省略)
var userinfo = make(map[string]int)
userinfo["userid"] = 21
userinfo["age"] = 18
fmt.Println(userinfo, userinfo["userid"])
// for range循环遍历
for k, v := range userinfo {
fmt.Println(k, v)
}
}
go map增删改查
package main
import "fmt"
func main() {
// make创建map类型数据make(map[string]int,长度可以省略)
var userinfo = make(map[string]int)
//增加
userinfo["userid"] = 21
userinfo["age"] = 18
//修改
userinfo["userid"] = 222
// 查找是否存在k
v, ok := userinfo["age"] // 存在ok=true,不存在ok=false
v1, ok1 := userinfo["ages"] // 存在ok=true,不存在ok=false
fmt.Println(userinfo)
fmt.Println(v, ok)
fmt.Println(v1, ok1)
//删除key delete()
delete(userinfo, "age")
fmt.Println(userinfo)
}
map类型的切片,切片类型的map
package main
import "fmt"
func main() {
// make创建map类型的切片
var userinfo = make([]map[string]string, 2, 2)
fmt.Println(userinfo[0])
fmt.Println(userinfo[0] == nil) //map初始值nil
if userinfo[0] == nil {
userinfo[0] = make(map[string]string)
userinfo[0]["username"] = "张三"
userinfo[0]["age"] = "24"
}
if userinfo[1] == nil {
userinfo[1] = make(map[string]string)
userinfo[1]["username"] = "张四"
userinfo[1]["age"] = "21"
}
fmt.Println(userinfo)
for _, v := range userinfo {
for key, value := range v {
fmt.Println(key, value)
}
}
// 值为切片的map
var userinfo2 = make(map[string][]string)
userinfo2["aaa"] = []string{
"吃饭",
"睡觉",
}
fmt.Println(userinfo2)
}