1.循环与判断
代码示例
package main
import "fmt"
func main() {
age := 19
if age > 10 {
fmt.Println("这是孩子")
} else if age > 35 {
fmt.Println("这是中年人")
} else {
fmt.Println("好好学习")
}
for i := 0; i < 10; i++ {
fmt.Println("你好靓仔")
}
}
golang有着类C语法,循环判断的if-else和for循环用法与C语言语法差不多
键值循环(for range)
- 例子
s := "靓仔"
for j, v := range s {
fmt.Printf("%d %c\n\n", j, v)
}
运行结果:
0 靓
//因为中文字符一般占3个字节,所以第一位0是靓仔,第三位3是仔
3 仔
- 作用
- 遍历数组,切片,字符串。map及通道。
- 区别
- 1.数组,切片,字符串返回索引和值
- 2.map返回键和值
- 3.通道只返回通道内的值
switch和goto
代码示例
package main
import (
"fmt"
)
func main() {
//当i=5时候就跳出循环
for i := 0; i < 10; i++ {
if i == 5 {
break
}
fmt.Println(i)
}
//当i=5时候,跳过此次for循环
for i := 0; i < 10; i++ {
if i == 5 {
continue
}
fmt.Println(i)
}
n := 2
switch n {
case 1:
fmt.Println("你是帅哥")
case 2:
fmt.Println("你很帅哦")
fallthrough
case 3:
fmt.Println("你好迷人")
}
//switch的第二种形式
switch w := 3; w {
case 1:
fmt.Println("你是美女")
case 2:
fmt.Println("你很美哦")
case 3:
fmt.Println("我爱你")
}
for i := 0; i < 4; i++ {
for j := 'a'; j < 'z'; j++ {
if j == 'c' {
goto xx
}
fmt.Printf("%v-%c\n", i, j)
}
}
xx: //label标签
fmt.Println("over")
}
fallthrough关键字
- 定义
- fallthrough可以执行满足条件case的下一个case
label标签
- 定义
- 在Golang中能使用Label的有goto,break,continue.
- 用法
- Label在continue, break中是可选的, 但是在goto中是必须的
- 作用范围: 定义Label的函数体内.
- Label可以声明在函数体的任何位置,不管Label声明在调用点的前面还是后面.
- 注意点
- 不能重复定义Label(也就是说不能有多个label)
- Label在嵌套函数(闭包)是不可用的. 不管是在闭包里调用闭包外的Label, 还是在闭包外调用闭包里的Label
- golang中也是发生在函数之间的,就是在一个函数中存在引用外部变量的行为,我们就称这是个闭包函数。
数组
代码示例
package main
import "fmt"
func main() {
var a1 [3]bool
var a2 [4]bool
fmt.Println("a1: a2:",a1,a2)
}
注意点
- 数组的长度是数组类型的一部分
- 比如 [3]int和[4]int都是长度固定的数组,==但它们两个的类型是不同的,因为长度不同。==
- 数组的可比较性
- 如果数组的长度不同,那么它们就属于不同类型,没有任何可比较性。
- 如果数组长度相等,则可以比较是否相等,当数组元素完全相等时,两个数组则相等。
- 让编译器来推断长度初始化数组
arr := [...]int{1, 2, 3}
- 数组是值类型
- 由于数组是值类型,所以在作为参数传递给一个函数时,传递的是值拷贝
切片
package main
import "fmt"
func main() {
//切片的定义
var s1 []int //定义一个存放int类型元素的切片
var s2 []string
fmt.Println(s1, s2)
s1 = []int{1, 2, 3}
s2 = []string{"帅哥", "美女", "大帅哥"}
fmt.Println(s1, s2)
fmt.Println(s1 == nil) //切片是引用类型,不支持直接比较,只能和nil比较
//长度和容量,len()函数求长度,cap()函数求容量
fmt.Printf("len:%d cap(s1):%d\n", len(s1), cap(s1))
fmt.Printf("len:%d cap(s2):%d\n", len(s2), cap(s2))
//由数组得到切片
a1 := [...]int{1, 2, 3, 4, 5, 6, 7, 8}
s3 := a1[0:4] //基于一个数组切割,左包含右不包含(左闭右开)
fmt.Println(s3)
s4 := a1[1:6]
fmt.Println(s4)
s5 := a1[:4] //=>[0:4]
s6 := a1[3:] //=>[3:len(a1)]
s7 := a1[:] //=>[0:len(a1)]
fmt.Println(s5, s6, s7)
//切片容量是指底层数组的容量
fmt.Printf("len(s5):%d cap(s5):%d\n", len(s5), cap(s5)) //len(s5):4 cap(s5):8
//底层数组从切片的第一个元素到最后的元素数量
fmt.Printf("len(s6):%d cap(s6):%d\n", len(s6), cap(s6)) //len(s6):5 cap(s6):5
//切片再切片
s8 := s6[3:]
fmt.Printf("len(s8):%d cap(s8):%d\n", len(s8), cap(s8)) //len(s8):2 cap(s8):2
//切片是引用类型,都指向底层的一个数组
fmt.Println("s6:", s6)
a1[6] = 1300
fmt.Println("s6", s6)
fmt.Println("s8:", s8)
}
知识点
创建切片
- 利用make函数创建切片
格式:slice := make([]类型, 长度,容量)
- 通过字面量创建切片
- 这种方法和创建数组类似,只是不需要指定[]运算符里的值。初始的长度和容量会基于初始化时提供的元素的个数确定
strSlice := []string{"帅哥", "美女", "我"}
- 数组和切片创建的区别
- 如果在[]运算符里指定了一个值,那么创建的就是数组而不是切片。只有在 [] 中不指定值的时候,创建的才是切片。
// 创建有 3 个元素的整型数组
myArray := [3]int{10, 20, 30}
// 创建长度和容量都是 3 的整型切片
mySlice := []int{10, 20, 30}
- nil切片
- 只要在声明时不做任何初始化,就会创建一个 nil 切片
var IntNum []int
- 空切片
- 空切片的底层数组中包含0个元素,也没有分配任何存储空间。一般用来表示空集合
// 使用 make 创建空的整型切片
myNum := make([]int, 0)
// 使用切片字面量创建空的整型切片
myNum := []int{}
内置函数
- append()
- append()函数为切片追加元素
- len()
- len()函数求切片长度
- cap()
- cap()函数求切片容量
注意点
- 切片获取
//由数组得到切片
a1 := [...]int{1, 2, 3, 4, 5, 6, 7, 8}
s3 := a1[0:4] //基于一个数组切割,左包含右不包含(左闭右开)
- 语法糖"..."
- 表示可变参数,用于表示可以接受任意个个数但类型相同的参数
- 切片都是引用类型
- 本质都指向底层数组