• go 复合数据类型


    数组

    数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。因为数组的长度是固定的,因此在Go语言中很少直接使用数组。

    数组声明方式:

    #第一种
    var balance [2] int
    balance =[2]int {1,2}
    #第二种
    var ba = [3] int {1,2,3}
    #第三种
    ba :=  [...] int {1,2,3}
    #数组可用索引访问,但是索引不支持负数
    #第四种
    r := [...]int{99: -1}#定义了一个含有100个元素的数组r,最后一个元素被初始化为-1,其它元素都是用0初始化

    数组遍历:

    #方法1
    var ba = [...] int {1,2,3}
        for i:=0;i<len(ba);i++ {
            print(ba[i])
        }
    #方法二
        for key,value := range ba{
            print(key)
            print(value)
        }

    Slice

    Slice(切片)代表变长的序列,序列中每个元素都有相同的类型。一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已。数组和slice之间有着紧密的联系。一个slice是一个轻量级的数据结构,提供了访问数组子序列(或者全部)元素的功能,而且slice的底层确实引用一个数组对象。一个slice由三个部分构成:指针、长度和容量。指针指向第一个slice元素对应的底层数组元素的地址,要注意的是slice的第一个元素并不一定就是数组的第一个元素。长度对应slice中元素的数目;长度不能超过容量,容量一般是从slice的开始位置到底层数据的结尾位置。内置的len和cap函数分别返回slice的长度和容量。多个slice之间可以共享底层的数据,并且引用的数组部分区间可能重叠。

    slice 声明

    切片不需要说明长度:
    var identifier []type
    make 可以用来声明切片
    var slice1 []type = make([]type, len) 简写也可以简写为slice1 := make([]type, len)
    也可以指定容量,其中capacity为可选参数。
    make([]T, length, capacity)
    
    s :=[] int {1,2,3 } 
    直接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是1,2,3.其cap=len=3
    
    s := arr[:] 
    初始化切片s,是数组arr的引用
    
    s := arr[startIndex:endIndex] 
    将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片
    
    s := arr[startIndex:] 
    默认 endIndex 时将表示一直到arr的最后一个元素
    
    s := arr[:endIndex] 
    默认 startIndex 时将表示从arr的第一个元素开始
    
    s1 := s[startIndex:endIndex] 
    通过切片s初始化切片s1
    
    s :=make([]int,len,cap) 
    通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片
    
    注意:如果切片操作超出cap(s)的上限将导致一个panic异常,但是超出len(s)则是意味着扩展了slice,因为新slice的长度会变大,

    因为slice值包含指向第一个slice元素的指针,因此向函数传递slice将允许在函数内部修改底层数组的
    元素。换句话说,复制一个slice只是对底层的数组创建了一个新的slice

    
    

    为何slice不直接支持比较运算符呢?这方面有两个原因。第一个原因,一个slice的元素是间接引用的,一个slice甚至可以包含自身。虽然有很多办法处理这种情形,但是没有一个是简单有效的。第二个原因,因为slice的元素是间接引用的,一个固定值的slice在不同的时间可能包含不同的元素,因为底层数组的元素可能会被修改。并且Go语言中map等哈希表之类的数据结构的key只做简单的浅拷贝,它要求在整个声明周期中相等的key必须对相同的元素。对于像指针或chan之类的引用类型,==相等测试可以判断两个是否是引用相同的对象。一个针对slice的浅相等测试的==操作符可能是有一定用处的,也能临时解决map类型的key问题,但是slice和数组不同的相等测试行为会让人困惑。因此,安全的做饭是直接禁止slice之间的比较操作。slice唯一合法的比较操作是和nil比较,一个零值的slice等于nil。一个nil值的slice并没有底层数组。一个nil值的slice的长度和容量都是0,但是也有非nil值的slice的长度和容量也是0的,例如[]int{}或make([]int,3)[3:]。与任意类型的nil值一样,我们可以用[]int(nil)类型转换表达式来生成一个对应类型slice的nil值。如果你需要测试一个slice是否是空的,使用len(s) == 0来判断,而不应该用s ==nil来判断。除了和nil相等比较外,一个nil值的slice的行为和其它任意0产长度的slice一样;例如reverse(nil)也是安全的。除了文档已经明确说明的地方,所有的Go语言函数应该以相同的方式对待nil值的slice和0长度的slice。内置的make函数创建一个指定元素类型、长度和容量的slice。

    slice append操作:

    func main() {
        var x, y []int
        for i := 0; i < 10; i++ {
            y = append(x, i)
            fmt.Printf("%d cap=%d	%v
    ", i, cap(y), y)
            x = y
        }
    }
    
    0 cap=1 [0]
    1 cap=2 [0 1]
    2 cap=4 [0 1 2]
    3 cap=4 [0 1 2 3]
    4 cap=8 [0 1 2 3 4]
    5 cap=8 [0 1 2 3 4 5]
    6 cap=8 [0 1 2 3 4 5 6]
    7 cap=8 [0 1 2 3 4 5 6 7]
    8 cap=16 [0 1 2 3 4 5 6 7 8]
    9 cap=16 [0 1 2 3 4 5 6 7 8 9]

    通常我们并不知道append调用是否导致了内存的重新分配,因此我们也不能确认新的slice和原始的slice是否引用的是相同的底层数组空间。同样,我们不能确认在原先的slice上的操作是否会影响到新的slice。因此,通常是将append返回的结果直接赋值给输入的slice变量:runes = append(runes, r)

    map

    哈希表是一种巧妙并且实用的数据结构。它是一个无序的key/value对的集合,其中所有的key都是不同的,然后通过给定的key可以在常数时间复杂度内检索、更新或删除对应的value。一个map就是一个哈希表的引用,map类型可以写为map[K]V,其中K和V分别对应key和value。map中所有的key都有相同的类型,所以的value也有着相同的类型,但是key和value之间可以是不同的数据类型。其中K对应的key必须是支持==比较运算符的数据类型,所以map可以通过测试key是否相等来判断是否已经存在。虽然浮点数类型也是支持相等运算符比较的,但是将浮点数用做key类型则是一个坏的想法,最坏的情况是可能出现的NaN和任何浮点数都不相等。对于V对应的value数据类型则没有任何的限制。

    内置的make函数可以创建一个map:
    ages := make(map[string]int)
    
    我们也可以用map字面值的语法创建map,同时还可以指定一些最初的key/value:
    ages := map[string]int{
      "alice": 31,
      "charlie": 34,
    }
    
    这相当于
    ages := make(map[string]int)
    ages["alice"] = 31
    ages["charlie"] = 34
    
    创建空的map的表达式是map[string]int{}

     结构体

    结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员。

    type Employee struct {
        ID int
        Name string
        Address string
        DoB time.Time
        Position string
        Salary int
        ManagerID int
    }
    1,   var dilbert Employee
    2, a := Employee{"ID":1}

    如果要在函数内部修改结构体成员的话,用指针传入是必须的;因为在Go语言中,所有的函数参数都是
    值拷贝传入的,函数参数将不再是函数调用时的原始变量。

    如果结构体的全部成员都是可以比较的,那么结构体也是可以比较的,那样的话两个结构体将可以使用==或!=运算符进行比较。相等比较运算符==将比较两个结构体的每个成员

  • 相关阅读:
    关于本站点(说明)
    对Python的认识以及以及Python变量简单的数据类型总结
    分享一个Ubuntu16.0.4安装MySQL5.7脚本
    Shell编程之批量安装服务脚本实例剖析
    Shell编程之批量安装服务脚本实例
    Shell编程之while&until循环详解
    Shell编程之case语句实战
    Shell编程之函数用法 (详解)
    Shell编程之if语句实战(详解)
    mongodb 查询语句笔记
  • 原文地址:https://www.cnblogs.com/tigerzhouv587/p/11414171.html
Copyright © 2020-2023  润新知