Go语言复习中,如何深入理解运算符、数组、切片、指针和map?

2026-05-22 08:302阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1483个文字,预计阅读时间需要6分钟。

Go语言复习中,如何深入理解运算符、数组、切片、指针和map?

如果什么都很容易,那还叫什么选择?走上床路肯定是有代价的。运算符++、+-、*、/、逻辑运算符||、!、位运算符|、^、赋值运算符=、==、!=、...和--是独立的语句,不属于赋值运算符。

如果什么都很容易,那还叫什么选择

走上坡路肯定是会累的

运算符

算术运算符 + - * /

逻辑运算符

&& || !

位运算符

<< | ^ &

Go语言复习中,如何深入理解运算符、数组、切片、指针和map?

赋值运算符

= += -= ...

++和--是独立的语句,不属于赋值运算符

比较运算符

< <= != ...

数组(Array)

var ages [30]int

var names [30]string

var nums [40]int

数组包含元素的类型和元素的个数。元素的个数(数组的长度)属于数据类型的一部分

数组是值类型

package main import "fmt" // day03复习 func main() { var name string name = "理想" fmt.Println(name) var ages [30]int // 声明了一个变量ages 它是[30]int类型 ages = [30]int{1, 2, 3, 4, 5} fmt.Println(ages) var ages2 = [...]int{1, 2, 3, 4} fmt.Println(ages2) var ages3 = [...]int{1: 100, 99: 200} fmt.Println(ages3) // 二维数组 // var a1 [3][2]int // [[1 2] [3 4] [5 6]] var a1 = [...][2]int { [2]int{1, 2}, [2]int{3, 4}, [2]int{5, 6}, } fmt.Println(a1) // 多维数组只有最外层可以使用... // 数组是值类型 x := [3]int{1, 2, 3} y := x // 把x的值拷贝了一份给了y y[1] = 200 // 修改的是副本y,并不影响x fmt.Println(x) // [1 2 3] f1(x) fmt.Println(x) // [1 2 3] } func f1(a [3]int) { // Go语言中的函数传递的都是值(Ctrl+c Crtl+v) a[1] = 100 // 此处修改的是副本的值 }

切片

切片的定义

切片不存值 它就像一个框 去底层数组框值

切片:指针、长度、容量

切片的扩容策略:

  1. 如果申请的容量大于原来的2倍,那就直接扩容至新申请的容量

  2. 如果小于1024,那么就直接两倍

  3. 如果大于1024,就按照1.25倍去扩容

  4. 具体存储的值类型不同,扩容策略也有一定的不同

append函数

指针

只需要记住两个符号:&和*

map

map存储的是键值对的数据

也是需要申请内存的

package main import "fmt" // day03复习 func main() { var name string name = "理想" fmt.Println(name) var ages [30]int // 声明了一个变量ages 它是[30]int类型 ages = [30]int{1, 2, 3, 4, 5} fmt.Println(ages) var ages2 = [...]int{1, 2, 3, 4} fmt.Println(ages2) var ages3 = [...]int{1: 100, 99: 200} fmt.Println(ages3) // 二维数组 // var a1 [3][2]int // [[1 2] [3 4] [5 6]] var a1 = [...][2]int { [2]int{1, 2}, [2]int{3, 4}, [2]int{5, 6}, } fmt.Println(a1) // 多维数组只有最外层可以使用... // 数组是值类型 x := [3]int{1, 2, 3} y := x // 把x的值拷贝了一份给了y y[1] = 200 // 修改的是副本y,并不影响x fmt.Println(x) // [1 2 3] f1(x) fmt.Println(x) // [1 2 3] // 切片(slice) // var s1 []int // 没有分配内存 == nil // fmt.Println(s1) // [] // fmt.Println(s1 == nil) // true // s1 = []int{1, 2, 3} // fmt.Println(s1) // // make初始化 分配内存 // s2 := make([]bool, 2, 4) // fmt.Println(s2) // [false false] // s3 := make([]int, 0, 4) // fmt.Println(s3 == nil) // false s1 := []int{1,2,3} // [1 2 3] s2 := s1 // var s3 []int // nil // var s3 = make([]int, 0, 3) var s3 = make([]int, 3, 3) copy(s3, s1) fmt.Println(s2) // [1 2 3] s2[1] = 200 fmt.Println(s2) // [1 200 3] fmt.Println(s1) // [1 200 3] fmt.Println(s3) // [] 没有内存 // var s1 []int // nil // // s1 = make([]int, 1) // // s1[0] = 100 // // fmt.Println(s1) // s1 = append(s1, 1) // 自动初始化切片 // fmt.Println(s1) // 指针 // Go语言里面的指针只能读不能修改 不能修改指针变量指向的地址 addr := "北京" addrP := &addr fmt.Println(addrP) // 0xc00003c240 内存地址 fmt.Printf("%T\n", addrP) // *string addrV := *addrP // 根据内存地址找值 fmt.Println(addrV) // map var m1 map[string]int fmt.Println(m1 == nil) m1 = make(map[string]int, 10) m1["理想"] = 100 fmt.Println(m1) fmt.Println(m1["西京"]) // 如果key不存在返回的是value对应类型的零值 score, ok := m1["西京"] // 如果返回值是布尔型 我们通常用OK去接受它 if !ok { fmt.Println("查不到西京") } else { fmt.Println("西京的分数是", score) } delete(m1, "理值") // 删除的key不存在什么都不干 delete(m1, "理想") fmt.Println(m1) // map[] fmt.Println(m1 == nil) // false 已经开辟了内存 } func f1(a [3]int) { // Go语言中的函数传递的都是值(Ctrl+c Crtl+v) a[1] = 100 // 此处修改的是副本的值 }

练习

package main import ( "fmt" "strings" "unicode" ) func main() { // 1. 判断字符串中汉字的数量 // 难点是判断一个字符是汉字 s1 := "Hello 中国" // 1. 依次拿到字符串中的字符 var count int for _, c := range s1 { // 2. 判断当前这个字符是不是汉字 if unicode.Is(unicode.Han, c) { count++ } } // 3. 把汉字出现的次数累加得到最终结果 fmt.Println(count) // 2. how do you do 单词出现的次数 s2 := "how do you do" // 2.1 把字符串安装空格切割得到切片 s3 := strings.Split(s2, " ") // 2.2 遍历切片存储到一个map m1 := make(map[string]int, 10) for _, w := range s3 { fmt.Println(w) // 1. 如果原来map中不存在w这个key那么出现次数=1 if _, ok := m1[w]; !ok { m1[w] = 1 } else { m1[w]++ } // 2. 如果map中存在w这个key,那么出现次数+1 } // 2.3 累加出现的次数 for key, value := range m1 { fmt.Println(key, value) } // 回文判断 // 字符串从左往右读和从右往左读是一样的,那么就是回文 // 上海自来水来自海上 s[0] s[len(s)-1] // 山西运煤车煤运西山 // 黄山落叶松叶落山黄 ss := "山西运煤车煤运西山" // 解题思路: // 把字符串中的字符拿出来放到一个[]rune中 r := make([]rune, 0, len(ss)) for _, c := range ss { r = append(r, c) } fmt.Println("[]rune:",r) for i := 0; i < len(r)/2; i++ { // 山 ss[0] ss[len(s)-1] // 西 ss[1] ss[len(s)-1-1] // 运 ss[2] ss[len(s)-1-2] // 煤 ss[3] ss[len(s)-1-3] // ... // c ss[i] ss[len(s)-1-i] if r[i] != r[len(r)-1-i] { fmt.Println("不是回文") return } } fmt.Println("是回文") }

本文共计1483个文字,预计阅读时间需要6分钟。

Go语言复习中,如何深入理解运算符、数组、切片、指针和map?

如果什么都很容易,那还叫什么选择?走上床路肯定是有代价的。运算符++、+-、*、/、逻辑运算符||、!、位运算符|、^、赋值运算符=、==、!=、...和--是独立的语句,不属于赋值运算符。

如果什么都很容易,那还叫什么选择

走上坡路肯定是会累的

运算符

算术运算符 + - * /

逻辑运算符

&& || !

位运算符

<< | ^ &

Go语言复习中,如何深入理解运算符、数组、切片、指针和map?

赋值运算符

= += -= ...

++和--是独立的语句,不属于赋值运算符

比较运算符

< <= != ...

数组(Array)

var ages [30]int

var names [30]string

var nums [40]int

数组包含元素的类型和元素的个数。元素的个数(数组的长度)属于数据类型的一部分

数组是值类型

package main import "fmt" // day03复习 func main() { var name string name = "理想" fmt.Println(name) var ages [30]int // 声明了一个变量ages 它是[30]int类型 ages = [30]int{1, 2, 3, 4, 5} fmt.Println(ages) var ages2 = [...]int{1, 2, 3, 4} fmt.Println(ages2) var ages3 = [...]int{1: 100, 99: 200} fmt.Println(ages3) // 二维数组 // var a1 [3][2]int // [[1 2] [3 4] [5 6]] var a1 = [...][2]int { [2]int{1, 2}, [2]int{3, 4}, [2]int{5, 6}, } fmt.Println(a1) // 多维数组只有最外层可以使用... // 数组是值类型 x := [3]int{1, 2, 3} y := x // 把x的值拷贝了一份给了y y[1] = 200 // 修改的是副本y,并不影响x fmt.Println(x) // [1 2 3] f1(x) fmt.Println(x) // [1 2 3] } func f1(a [3]int) { // Go语言中的函数传递的都是值(Ctrl+c Crtl+v) a[1] = 100 // 此处修改的是副本的值 }

切片

切片的定义

切片不存值 它就像一个框 去底层数组框值

切片:指针、长度、容量

切片的扩容策略:

  1. 如果申请的容量大于原来的2倍,那就直接扩容至新申请的容量

  2. 如果小于1024,那么就直接两倍

  3. 如果大于1024,就按照1.25倍去扩容

  4. 具体存储的值类型不同,扩容策略也有一定的不同

append函数

指针

只需要记住两个符号:&和*

map

map存储的是键值对的数据

也是需要申请内存的

package main import "fmt" // day03复习 func main() { var name string name = "理想" fmt.Println(name) var ages [30]int // 声明了一个变量ages 它是[30]int类型 ages = [30]int{1, 2, 3, 4, 5} fmt.Println(ages) var ages2 = [...]int{1, 2, 3, 4} fmt.Println(ages2) var ages3 = [...]int{1: 100, 99: 200} fmt.Println(ages3) // 二维数组 // var a1 [3][2]int // [[1 2] [3 4] [5 6]] var a1 = [...][2]int { [2]int{1, 2}, [2]int{3, 4}, [2]int{5, 6}, } fmt.Println(a1) // 多维数组只有最外层可以使用... // 数组是值类型 x := [3]int{1, 2, 3} y := x // 把x的值拷贝了一份给了y y[1] = 200 // 修改的是副本y,并不影响x fmt.Println(x) // [1 2 3] f1(x) fmt.Println(x) // [1 2 3] // 切片(slice) // var s1 []int // 没有分配内存 == nil // fmt.Println(s1) // [] // fmt.Println(s1 == nil) // true // s1 = []int{1, 2, 3} // fmt.Println(s1) // // make初始化 分配内存 // s2 := make([]bool, 2, 4) // fmt.Println(s2) // [false false] // s3 := make([]int, 0, 4) // fmt.Println(s3 == nil) // false s1 := []int{1,2,3} // [1 2 3] s2 := s1 // var s3 []int // nil // var s3 = make([]int, 0, 3) var s3 = make([]int, 3, 3) copy(s3, s1) fmt.Println(s2) // [1 2 3] s2[1] = 200 fmt.Println(s2) // [1 200 3] fmt.Println(s1) // [1 200 3] fmt.Println(s3) // [] 没有内存 // var s1 []int // nil // // s1 = make([]int, 1) // // s1[0] = 100 // // fmt.Println(s1) // s1 = append(s1, 1) // 自动初始化切片 // fmt.Println(s1) // 指针 // Go语言里面的指针只能读不能修改 不能修改指针变量指向的地址 addr := "北京" addrP := &addr fmt.Println(addrP) // 0xc00003c240 内存地址 fmt.Printf("%T\n", addrP) // *string addrV := *addrP // 根据内存地址找值 fmt.Println(addrV) // map var m1 map[string]int fmt.Println(m1 == nil) m1 = make(map[string]int, 10) m1["理想"] = 100 fmt.Println(m1) fmt.Println(m1["西京"]) // 如果key不存在返回的是value对应类型的零值 score, ok := m1["西京"] // 如果返回值是布尔型 我们通常用OK去接受它 if !ok { fmt.Println("查不到西京") } else { fmt.Println("西京的分数是", score) } delete(m1, "理值") // 删除的key不存在什么都不干 delete(m1, "理想") fmt.Println(m1) // map[] fmt.Println(m1 == nil) // false 已经开辟了内存 } func f1(a [3]int) { // Go语言中的函数传递的都是值(Ctrl+c Crtl+v) a[1] = 100 // 此处修改的是副本的值 }

练习

package main import ( "fmt" "strings" "unicode" ) func main() { // 1. 判断字符串中汉字的数量 // 难点是判断一个字符是汉字 s1 := "Hello 中国" // 1. 依次拿到字符串中的字符 var count int for _, c := range s1 { // 2. 判断当前这个字符是不是汉字 if unicode.Is(unicode.Han, c) { count++ } } // 3. 把汉字出现的次数累加得到最终结果 fmt.Println(count) // 2. how do you do 单词出现的次数 s2 := "how do you do" // 2.1 把字符串安装空格切割得到切片 s3 := strings.Split(s2, " ") // 2.2 遍历切片存储到一个map m1 := make(map[string]int, 10) for _, w := range s3 { fmt.Println(w) // 1. 如果原来map中不存在w这个key那么出现次数=1 if _, ok := m1[w]; !ok { m1[w] = 1 } else { m1[w]++ } // 2. 如果map中存在w这个key,那么出现次数+1 } // 2.3 累加出现的次数 for key, value := range m1 { fmt.Println(key, value) } // 回文判断 // 字符串从左往右读和从右往左读是一样的,那么就是回文 // 上海自来水来自海上 s[0] s[len(s)-1] // 山西运煤车煤运西山 // 黄山落叶松叶落山黄 ss := "山西运煤车煤运西山" // 解题思路: // 把字符串中的字符拿出来放到一个[]rune中 r := make([]rune, 0, len(ss)) for _, c := range ss { r = append(r, c) } fmt.Println("[]rune:",r) for i := 0; i < len(r)/2; i++ { // 山 ss[0] ss[len(s)-1] // 西 ss[1] ss[len(s)-1-1] // 运 ss[2] ss[len(s)-1-2] // 煤 ss[3] ss[len(s)-1-3] // ... // c ss[i] ss[len(s)-1-i] if r[i] != r[len(r)-1-i] { fmt.Println("不是回文") return } } fmt.Println("是回文") }