(七)Go语言内建容器-数组/Slice切片/Map/字符

一.Go语言的数组

     这边的样例子都有亲自跑过,之所以没有贴代码,图片显得比较直观点

     

    Go语言数组的特点:

    1. 可以通过_省略变量

    2. 不仅range,任何地方都可以_来省略变量

    3. [10]int 和 [20]int 是不同类型, 数组在函数中的传递,会拷贝数组

    4. 在go语言一般不直接用数组

二. Go语言切片

      概念:切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型

     切片特性:

  • 取出的元素数量为:结束位置 - 开始位置;
  • 取出元素不包含结束位置对应的索引,切片最后一个元素使用 slice[len(slice)] 获取;
  • 当缺省开始位置时,表示从连续区域开头到结束位置;
  • 当缺省结束位置时,表示从开始位置到整个连续区域末尾;
  • 两者同时缺省时,与切片本身等效;
  • 两者同时为 0 时,等效于空切片,一般用于切片复位

   下面几个代码片段:

  1.指定范围中生成切片 ==> slice [开始位置 : 结束位置]

// slice [开始位置 : 结束位置] 用法
var initArr = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println("array [2:6] = ", initArr[2:6]) // 输出结果(半包半闭):array [2:6] =  [2 3 4 5]
fmt.Println("array [2:] = ", initArr[2:])   // 输出结果:array [2:] =  [2 3 4 5 6 7]
fmt.Println("array [:6] = ", initArr[:6])   // 输出结果:array [:6] =  [0 1 2 3 4 5]
fmt.Println("array [:] = ", initArr[:])     // 输出结果:array [:] =  [0 1 2 3 4 5 6 7]

  2.slice通过函数调用值的变化

  注意:发现不管是初始的initArr,还是sliceArr对应的值都发生了改变,所以slice本身没有数据,是对底层array的一个view

func updateSlice(s []int) {
    s[0] = 100
}

func main() {
    // 第一段代码,slice通过函数修改完之后值的变化
    sliceArr := initArr[:]
    fmt.Println("sliceArr = ", sliceArr) // [0 1 2 3 4 5 6 7]
    updateSlice(sliceArr)
    fmt.Println("sliceArr = ", sliceArr) // [100 1 2 3 4 5 6 7]
    fmt.Println("initArr = ", initArr)   // [100 1 2 3 4 5 6 7]
    sliceArr = initArr[2:]
    fmt.Println("sliceArr = ", sliceArr) // [2 3 4 5 6 7]
    updateSlice(sliceArr)
    fmt.Println("initArr = ", initArr) // [100 1 100 3 4 5 6 7]
}

 3.声明新的切片

  • 切片是动态结构,只能与 nil 判定相等,不能互相判定相等。
  • 声明但未使用的切片的默认值是 nil
// 声明新的切片
var newSliceInt []int
var newSliceString []string
var newSliceInitInt = []int{}
var sliceCreateByMake = make([]int, 10, 18)                                  // 通过make来创建切片,第一个参数表示len,第二个参数cap
fmt.Println(newSliceInt, newSliceString, newSliceInitInt, sliceCreateByMake) // 输出的结果:[] [] []
fmt.Println(newSliceInt == nil)                                              // 输出的结果:true
fmt.Println(newSliceString == nil)                                           // 输出的结果:true
fmt.Println(newSliceInitInt == nil)                                          // 输出的结果:false

4.slice的扩展

// 看这段代码段时候,是不是有个疑问:为什么s1只有到5,s2是基于s1得出段结果,确可以输出6
var initArr = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s1 := initArr[2:6]
s2 := s1[3:5]
fmt.Println(s1, s2) // 输出结果:[2 3 4 5] [5 6]

fmt.Printf("s1=%v,len=%d,cap=%d \n", s1, len(s1), cap(s1)) // 输出结果:s1=[2 3 4 5],len=4,cap=6
fmt.Printf("s2=%v,len=%d,cap=%d \n", s2, len(s2), cap(s2)) // 输出结果:s2=[5 6],len=2,cap=3

  原理:

  •  slice可以向后扩展,不可以向前扩展
  •  s[i]不可超越len(s),向后扩展不可超越底层数组cap(s)

5.slice(切片)的操作(增,删,改)

func main() {
	// 看这段代码段时候,是不是有个疑问:为什么s1只有到5,s2是基于s1得出段结果,确可以输出6
	var initArr = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
	s1 := initArr[2:6]
	s2 := s1[3:5]
	// fmt.Println(s1, s2) // 输出结果:[2 3 4 5] [5 6]
	fmt.Printf("s1=%v,len=%d,cap=%d \n", s1, len(s1), cap(s1)) // 输出结果:s1=[2 3 4 5],len=4,cap=6
	fmt.Printf("s2=%v,len=%d,cap=%d \n", s2, len(s2), cap(s2)) // 输出结果:s2=[5 6],len=2,cap=3

	// slice的添加
	s3 := append(s2, 10) // [5 6 10] 这时候还是initArr的view,所以initArr打印出来的时候会有新增进去的10
	s4 := append(s3, 17) // [5 6 10 17] 这时候就不是initArr的view,系统会默认创建个数组
	s5 := append(s4, 25) // [5 6 10 17 25] 这时候就不是initArr的view,系统会默认创建个数组
	fmt.Println(initArr) // [0 1 2 3 4 5 6 10]

	// slice的复制
	copy(s5, s1)    // 我们将s1拷贝至s5,首先s5:[5 6 10 17 25], s1:[2 3 4 5]
	fmt.Println(s5) // 输出结果:[2 3 4 5 25]

	// slice的删除
	s5 = append(s5[:2], s5[3:]...) // 初始值:[2 3 4 5 25],假如我们要删除s5第2个元素4
	fmt.Println(s5)                // 输出结果:[2 3 5 25]
}
  • 添加元素时如果超越cap,系统会重新分配更大的数组
  • slice添加元素的操作 s = append(s, value)
  • 添加时候,如果cap容纳不下,cap 会在基础上* 2
  • append添加数组的时候可以在后面加...

三.Go语言的MAP

// map的声明
m1 := map[string]string{
    "name":     "mk",
    "age":      "18",
    "province": "fujian",
}
var m2 map[string]int      // m2 == nil
m3 := make(map[string]int) // m3 == empty map
fmt.Println(m1, m2, m3)

// map的遍历
for k, v := range m1 {
    fmt.Println(k, v)
}

// 获取元素
name, ok := m1["name"]
city, ok2 := m1["city"]
fmt.Println(name, ok)  // 输出 mk true
fmt.Println(city, ok2) // 输出 false

// 删除元素
delete(m1, "name")
if name, ok := m1["name"]; ok {
    fmt.Println(name, ok)
} else {
    fmt.Println("don't exit") // 输出 don't exit
}
  • key不存在的时候,会获取value的初始值
  • 用value, ok := m[key]可以来判断是否存在该key
  • 用delete来删除一个key
  • 遍历的时候,不保证遍历顺序,如需,自己手动排序
  • 除了slice,map,func的内建类型都可以做成key
  • struct不包括上述类型,也可以做成key

四.Go语言的字符及字符处理

func main() {
	chineseString := "I爱中国!"
	fmt.Println(len(chineseString))    //  输出结果:11,每个中文占3个字节
	for i, ch := range chineseString { // ch 就是rune ,四个字节
		fmt.Printf("(%d)%X ", i, ch) // 输出结果:(0)49 (1)7231 (4)4E2D (7)56FD (10)21
	}
	fmt.Println(utf8.RuneCountInString(chineseString)) // 获取字符数量

	for i, ch := range []rune(chineseString) {
		fmt.Printf("%d%c ", i, ch)
	}
}
  • 使用range去遍历rune对
  • 使用utf8.RuneCountInString可以获取字符数量
  • 使用len获取字节的长度
  • 使用[]byte获取字节
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值