GO语言入门第二节 GO语言常用数据结构

Go 语言常用数据结构

1. 数组和切片

  • 数组

    • 数组的声明

      //声明一个长度是3的数组,初始话为0值
      var a [3]int
      a[0] = 1
      
      //声明数组的同时初始化
      b := [3]int{1,2,3}
      c := [2][2] int {{1,2},{3,4}}
      //声明一个不定长数组
      d := [...]int {1,2,3,4,5,6}
      
    • 数组的遍历

      //使用for进行遍历(这里也可以进行普通的下标进行遍历)
      for _ /*索引值,下划线表示占位,不使用*/,e /*元素值*/:= range a{
        t.Log("占位循环:",e)
      }
      
    • 数组截取

      语句的表达式如下

      a[开始索引(包含):结束索引(不包含)]

      不包含结束索引是为了防止使用数组长度作为结束索引时发生下标越界

  • 切片

    • 切片结构体的基本元素

      • ptr:指向一个数组的指针
      • len:我们可以访问的元素个数
      • cap:后端空间的长度(和元素个数很像,类似于java里ArrayList的容量和数组长度,当元素个数超入容量了之后会直接发生两倍的扩容)
    • 切片的声明

    • //声明一个切片
      var s0 []int;
      t.Log(cap(s0),len(s0))//0 0
      
      //往切片里添加一个元素
      s0 = append(s0, 1);
      t.Log(cap(s0),len(s0))//1 1 
      
      //创建一个数组长度是2,容量是3的切片
      s1 := make([]int,2,3)
      t.Log(cap(s1),len(s1))//3 2
      

      要注意的是,使用append函数往切片里添加元素的时候原来的切片并不会改变(切片是不可变对象?),需要把这个的返回值重新赋值给原来的切片。也就是说如果频繁的使用这种方式网切片里添加元素就会导致大量的内存垃圾触发垃圾回收

    • 切片共享的存储结构

      使用多个切片指向同一个存储空间

      month := []int {1,2,3,4,5,6,7,8,9,10,11,12}
      q2 := month[3:6]
      t.Log(len(q2),cap(q2))// 3 9
      summer := month[4:7]
      t.Log(len(summer), cap(summer))// 3 8
      

      需要注意的是,当我们改变任意一个切片,由于底层修改了内存里的数据,其他切片仍然会被一起修改

  • 数组和切片的比较

    比较项 数组 切片
    容量是否可伸缩
    是否可以进行比较 只能判断是否为nil

2. Map

  • Map的声明和使用

    m := map[键类型] 值类型 {键:值 ,...}

    // 声明一个Map
    m := map[string] int {"one":1,"two":2,"three":3}
    t.Log(m["one"])//1
    
    
    //使用make声明一个map
    m2 := make(map[string] int,10)
    //往map里添加键值对
    m2["add"] = 1//1
    

    需要注意的是,当我们在map里查找一个不存在的key的时候,返回的是一个0值。为了区分到底是0值还是该键值对不存在,在获取map的值时会返回一个bool值来表示是否是键值对不存在,true表示存在,false表示不存在

    value,ok := m2["one"]
    t.Log(value,ok)// 0,false
    value,ok = m2["add"]
    t.Log(value,ok)// 1,true
    
  • map的遍历

    使用遍历数组时一样可以使用的range来遍历map

    for k,v := range m{
      t.Log(k,":",v)
    }
    
  • map与工厂模式

    map的value可以时函数类型,如下

    m := map[int]func(op int) int{}
    m[1] = func(op int) int {return op}
    m[2] = func(op int) int {return op*op}
    m[3] = func(op int) int {return op*op*op}
    t.Log(m[1](2),m[2](2),m[3](2))//2 4 8
    
    • map构建set集合

      我们可以利用map [type]bppl来实现set集合(go没有内置set的数据结构),使用name来保存你想要的元素,放入元素以后把value置为 true。

      这样当我们尝试在这个map里取不存在的name的时候,会默认返回0值(false),重复放入元素的时候由于name的唯一性也不会造成重复内容

3. 字符串

  • 与其他语言的差异

    • string时一个基本数据类型,会初始化为0值,不是指针或引用类型
    • string时只读的不可变的字节切片,len时他包含的字节数(不是字符数
    • string的byte数组可以存放任何数据(包括二进制数据)
  • Unicode和UTF-8

    • Unicode时一种字符集
    • UTF-8时Unicode的存储实现
    s := "中"
    c := []rune(s)
    t.Log(len(c),len(s)) // 1 3
    t.Logf("中 unicode %x",c[0]) // 中 unicode 4e2d
    t.Logf("中 UTF-8 %x",s) // 中 UTF-8 e4b8ad
    
    key value
    字符 "中"
    Unicode 0x4E2D
    UTF-8 0xE4B8AD
    字节数组 [0x4E, 0xB8, 0xAD]
  • string的高级功能

    • 字符串分割

      string[] strings,Split(待分割的字符串, 分割的依据)

    • 字符串拼接

      string strings.jion(字符串数组, 中间间隔的字符串)

    • string和数值的转换

      string strove.Itia(数值) 数转字符串

      number,bool strove.Atoi(字符串) 字符串转数,返回的bool是是否成功

4.函数

  • Go语言中函数的特点

    • 可以有多个返回值

    • func funcDemo()(int,int){
          //返回两个随机数
          return rand.Intn(10),rand.Intn(20)
      }
      
    • 所有的参数传递都是值传递(切片和map都是值传递,而然他们中的数据是指针,所以修改他们实际上修改的都是后端地址保存的数据)

    • 函数可以作为变量的值

    • 函数可以作为另一个函数的参数和返回值(下面是一个函数作为参数的例子:函数运行时间计时器)

      //入口函数
      func TestFunc(t *testing.T) {
          a,b := funcDemo()
          t.Log(a,b)
          a,b = timeSpent(funcDemo)
          t.Log(a,b)
      }
      
      //需要计时的函数
      func funcDemo()(int,int){
          //返回两个随机数
          return rand.Intn(10),rand.Intn(20)
      }
      
      //计时函数的函数,需要传入一个函数(但是现在这个函数的定义必须要符合规则)
      func timeSpent(inner func()(int, int)) (int,int) {
          start := time.Now()
          ret1,ret2 := inner()
          fmt.Println("用时:",time.Since(start).Nanoseconds())
          return ret1,ret2
      }
      
  • 函数的可变参数

    不需要指定参数的个数,传入多少接受多少。底层通过数组来实现,相当于传入数组

    func add (param ...int) int {
      result := 0;
      for v,_ := range param {
          result += v
      }
      return result
    }
    
  • defer函数

    被defer关键字修饰的函数调用不会立即执行函数题,而是先执行下面语句,在程序段返回的时候才会执行(相当于Java中的finally语句块)

    func TestDefer(t *testing.T) {
      defer finallyFunc()
      fmt.Println("开始执行")
      //执行一次异常, 发现defer语句块仍然执行了
      panic("err")
    }
    
    func finallyFunc() {
      fmt.Println("一定会执行的语句块")
    }
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,770评论 0 38
  • 1.安装 https://studygolang.com/dl 2.使用vscode编辑器安装go插件 3.go语...
    go含羞草阅读 1,546评论 0 6
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,694评论 0 3
  • fmt格式化字符串 格式:%[旗标][宽度][.精度][arg索引]动词旗标有以下几种:+: 对于数值类型总是输出...
    皮皮v阅读 1,090评论 0 3
  • 走进reading town,做好我自己,影响更多人。亲子阅读记录--2月第4周 本周书单:《不一样的卡梅拉》,《...
    小时光倩阅读 276评论 0 0