数组
声明定义、初始化和赋值
var 变量名 [数量]类型
,例如:var array [3]int
,声明三个元素的整型类型数组。c
初始化:var array [2]int = [3]int{1, 2, 3}
,使用自动推导类型var array = [3]int{1, 2, 3}
,简短形式:array := [3]int{1, 3}
动态推导大小数组声明:array := [...]int{1, 3, 3}
可以使用别名定义数组,例如type array3 [3]int
初始化某个位置的值:array := [3]int{2:4}
索引赋值:array[3] = 100
Go的数组可以直接赋值,而且不是共享一份数据,例如:
package main
import "fmt"
func main() {
array1 := [3]int{1, 2, 3}
array2 := [3]int{11, 12, 13}
array2 = array1
array2[1] = 100
fmt.Println(array1)
fmt.Println(array2)
}
// output
// [1 2 3]
// [1 100 3]
取值方式
-
索引下标, array[1]
-
for range
package main
import "fmt"
func main() {
var array [3]int
// for _, value:= range array 不需要索引
for index, value := range array {
fmt.Printf("index=%d, value=%dn", index, value)
}
}
数组对比
可以直接使用运算符==
和!=
来进行比较数组是否相等,只有两个数组类型相同、大小相同、值相同时才会相等。
package main
import "fmt"
func main() {
array := [3]int{2: 4}
array2 := [3]int{0, 0, 4}
fmt.Println(array2 == array)
}
// output: true
多维数组
方式与一维数组一样,只是元素还是一个数组。
声明:var array [2][3]int
,两行三列的矩阵。
package main
import "fmt"
func main() {
metrics :=[2][3]int{{1, 2, 3}, {11, 12, 13}}
for _, metric := range metrics {
for _, value := range metric {
fmt.Printf("%d, ", value)
}
fmt.Println()
}
}
// output
// 1, 2, 3,
// 11, 12, 13,
切片
定义
切片可以类比Java的List
,底层数据结构是数组,切片是数组的左闭右开的区间。
Go切片内部结构:
-
地址 -
大小 -
容量
slice [begin:end]
构造方法
从数组获取切片方式
package main
import "fmt"
func main() {
var array = [3]int{1, 2, 3}
fmt.Println(array[0:2])
fmt.Println(array[:2])
fmt.Println(array[1:])
fmt.Println(array[:])
}
// output
[1 2]
[1 2]
[2 3]
[1 2 3]
直接声明新切片
package main
import "fmt"
func main() {
var list []int
var list2 = []int{} //声明并初始化
fmt.Println(list)
fmt.Println(list2)
fmt.Println(list == nil)
fmt.Println(list2 == nil)
}
// output
[]
[]
true
false
切片追加元素:
package main
import "fmt"
func main() {
var list []int
list = append(list, 1)
fmt.Println(list)
}
切片是动态结构,与数组不一样,两个切片不能直接用运算符进行比较,只能与nil
进行运算符比较。
使用make()
函数构造切片
使用方式:make([]type, size, cap)
初始化size个零值,容量位cap的切片
package main
import "fmt"
func main() {
list1 := make([]int, 2, 10)
list2 := make([]int, 3, 10)
list1 = append(list1, 1)
fmt.Println(list1, list2, len(list1), len(list2))
}
// output
// [0 0 1] [0 0 0] 3 3
切片复制
使用内置函数:func copy(dst, src []Type) int
package main
import "fmt"
func main() {
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{11, 22, 33}
fmt.Println(copy(slice1, slice2), slice1)
}
// output
// 3 [11 22 33 4 5]
map
定义
map是无序的键值对的集合,可以通过key哈希快速检索数据,map结构不是线程安全的。
var name map[keyType]valueType
,例如:var hashMap map[int]int
,map定义不需要指定大小,map可以动态增长,未初始化的map的值是nil
。
构造方式
类型声明
package main
import "fmt"
func main() {
var hashMap = map[string]string{"name": "erpang", "gender": "male"}
hashMap["school"] = "university"
fmt.Printf("%s, %s", hashMap["name"], hashMap["school"])
}
// output
// erpang, university
make构造
make(map[keyType]valueType)
或者make(map[keyType]valueType)
map遍历
package main
import "fmt"
func main() {
hashMap := make(map[string]string)
hashMap["school"] = "university"
hashMap["name"] = "erpang"
for key, value := range hashMap {
fmt.Printf("key:%s, value:%sn", key, value)
}
}
map没有提供清空map的方法,可以重新定义赋值进行清空。
线程安全的map
Go 1.9提供了并发安全的sync.Map
类型
示例:
package main
import (
"fmt"
"sync"
)
func main() {
concurrentMap := sync.Map{}
concurrentMap.Store("name", "erpang")
concurrentMap.Store("gender", "male")
fmt.Println(concurrentMap.Load("name"))
concurrentMap.Range(func(key, value any) bool {
fmt.Printf("key:%s, value:%sn", key, value)
return true
})
}
条件控制
if
示例:
package main
import "fmt"
func main() {
num := 1
if num > 1 {
fmt.Printf("num > 1")
} else if num < 1 {
fmt.Printf("num < 1")
} else {
fmt.Printf("num = 1")
}
// 添加执行语句,可以控制变量的作用域
if returnNum := 10; returnNum == 10 {
fmt.Printf("returnNum = 10")
}
}
for
Go只支持for
循环
示例:
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum++
}
fmt.Println(sum)
// 本质死循环
for {
sum++
if sum > 20 {
break
}
}
fmt.Println(sum)
for sum < 30 {
sum++
}
fmt.Println(sum)
}
// output
10
21
30
跳出循环的三种方式return
,break
,continue
,panic
for range
用于遍历数组、map、切片、字符串和管道
for key, value := range list {
}
value 是只读的拷贝,修改数据不会影响源数据,key对应不同的结构是不同的值,比如数组是索引,map是key
switch
switch 的分支表达式可以是任何类型,而且case之后不需要显示调用break打断,多个case值可以用,
分割。
如果case满足之后又需要执行下面的case,可以添加关键字fallthrough
,此时下方的紧跟的第一个case表达式无论是否满足,都会指向case
的语句。
示例:
package main
import "fmt"
func main() {
age := 6
switch age {
case 1:
fmt.Println(1)
case 2:
fmt.Println(2)
case 3, 4, 5:
fmt.Println(3, 4, 5)
case 6:
fmt.Println(6)
fallthrough
case 7:
fmt.Println(7)
default:
fmt.Println(age)
}
}
// output
6
7
原文始发于微信公众号(erpang coding):Golang基础知识二
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/37408.html