zoukankan      html  css  js  c++  java
  • cafebabe go入门练习004:数组和切片

    数组

    数组是固定长度的特定类型元素的序列。数组的大小是数组定义的一部分,所以两个大小不同的数组是两个不同的类型,当然也不能比较。

    数组的定义方式:

    func main() {
    	var a [3]int
    	b := [3]int{1, 2, 3}
    	c := [...]int{1, 2, 3}
    	d := [...]int{1: 2, 0: 1, 2: 3}
    
    	fmt.Println(a)
    	fmt.Println(b)
    	fmt.Println(c)
    	fmt.Println(d)
    }
    

    go中函数传参一般都是值传递的,数组传参也是如此。如果确实要达到引用传递(pass arrays by reference)的效果,必须定义参数类型为指针。更好的方式是使用切片。

    切片

    go中数组使用很不灵活,因此需要一种灵活访问数组子序列的数据结构,这便是切片。

    切片由三部分组成:

    • data: 指针,切片起始位置指向的底层数组元素,并不一定是数组的第一个元素;
    • length:切片大小
    • capacity:切片容量,data指向的底层数组元素到最后一个元素。显然length<=capacity

    切片和数组的关系如图:

    所以,可以通过切片达到修改数组的目的,如反转数组元素:

    // reverse reverses a slice of ints in place.
    func reverse(s []int) {
          for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
                s[i], s[j] = s[j], s[i]
          }
    }
    

    切片一般从底层序列定义而来,作为独立的数据结构,当然也可以直接定义:

    func main() {
    	var a []int
    	fmt.Printf("a==nil:%t	len=%d	cap=%d
    ", a == nil, len(a), cap(a))
    	b := []int(nil)
    	fmt.Printf("b==nil:%t	len=%d	cap=%d
    ", b == nil, len(b), cap(b))
    	c := []int{}
    	fmt.Printf("c==nil:%t	len=%d	cap=%d
    ", c == nil, len(c), cap(c))
    	d := make([]int, 0, 0)
    	fmt.Printf("d==nil:%t	len=%d	cap=%d
    ", d == nil, len(d), cap(d))
    }
    

    输出如下:所以切片的零值是nil,但依然可以访问它,go确实更安全。

    模拟append函数:

    //append y to slice x
    func appendInt(x []int, y int) []int {
    	var z []int
    	zlen := len(x) + 1
    	if zlen < cap(x) {
    		//空间够,z直接从x扩展来
    		z = x[:zlen]
    	} else {
    		//扩容,2倍速增长
    		zcap := zlen
    		if zcap < 2*len(x) {
    			zcap = 2 * len(x)
    		}
    		z = make([]int, zlen, zcap)
    		copy(z, x)
    	}
    	z[len(x)] = y
    	return z
    }
    

    slice实现栈

    stack = append(stack, v) // push v
    top := stack[len(stack)-1] // top of stack
    stack = stack[:len(stack)-1] // pop
    

    slice删除中间位置

    func remove(slice []int, i int) []int {
          copy(slice[i:], slice[i+1:])
          return slice[:len(slice)-1]
    }
    
  • 相关阅读:
    SpringBoot整合redis
    maven dependency全局排除
    Spring Boot程序接收命令行参数
    MySQL8.0.20安装详解
    ITRS/GCRS/J2000坐标系的相互转换
    SpringBoot日记——日志框架篇
    SpringBoot集成log4j,解决log4j.properties不生效问题
    Office
    git下载
    WINDOWS上KAFKA运行环境安装
  • 原文地址:https://www.cnblogs.com/teacherma/p/13857439.html
Copyright © 2011-2022 走看看