《Go程序设计语言》- 第4章:复合数据类型

前言

本专栏是笔者在学习《Go程序设计语言》这本书时,对每个章节认为较为重要容易忘记👻)的知识点记录的笔记,其中也会有少量的思考👀, 现整理成博客分享出来。

如果对专栏感兴趣,跑过去看一眼,书中的每一章都有:《Go程序设计语言》笔记

❗️注意❗️:本专栏不是详细的知识讲解,只是碎片的知识条目,或可作为Go知识点查漏补缺的小工具~

数组

  1. 数组具有固定长度,声明:var a [4]int ;很少直接使用数组,一般都用slice
  2. 声明时自动初始化长度:var a [...]int{1,2,3},自动初始化长度为3
  3. 数组长度必须在编译时确定
  4. 声明并初始化数组时,可以提供给定位置上的元素值:var a [...]int{1:23, 2:34}
  5. crypto/sha256.Sum256()可以计算[]byteSHA256摘要;

slice

  1. slice有三个属性:指针,长度,容量容量大小通常是从slice其实元素,到底层数组的最后一个元素之间的元素个数;
  2. 指针指向第一个可从slice中访问的元素,但它并不一定是数组的第一个元素;
  3. 可以使用len cap分别获取slice的长度、容量;
  4. 和数组不同的是,slice无法作比较,因此不能用==来测试两个slice是否拥有相同元素;对于[]byte可以使用bytes.Equal来比较;
    • slice有可能包含它自身;
    • slice的元素在生命周期内可能变化,而散列表仅对元素做浅拷贝,所以不能作为map的键;
  5. slice唯一允许的是和nil作比较;相等时,slice的长度和容量都是0
  6. 可以使用make([]T, len, cap)创建一个slice;使用copy函数复制元素,返回复制的元素个数,是两个slice长度的较小值;
  7. 可以使用append函数来追加元素,在需要时会扩展一倍容量,以减小内存分配次数,将原slice数据复制到其中,再返回新的slice;一般会将调用结果赋值给传入的slicesli = append(sli, x)
  8. 对于任何函数,只要有可能改变slice的长度或容量,或使之指向不同数组,都应该更新slice变量;

map

  1. map中的键必须是可以通过==来比较的数据类型,所以slice不可以作为键;
  2. 使用make(map[KeyType]ValueType)来声明一个map
  3. 使用内置函数delete来移除元素;即使没有传入的键对应的值也是安全的;
  4. 无法获取map元素的地址,因为随着map的增长可能导致已有元素被重新散列到新的存储位置,使得地址无效;
  5. 使用for k, v := range mymap来迭代获取键值对,但迭代顺序是不固定的
  6. nilmap中添加元素会导致宕机
  7. 无论map是否有键k对应的值,都能获取到值,可以通过额外返回bool值确定:v, ok:= mymap[k]
  8. mapslice一样,只能和nil比较;

结构体

  1. 结构体变量或者结构体指针均采用.访问成员
  2. 成员变量的顺序不同,是不同的结构体;但一般只关注变量的组合;
  3. 如果成员变量名称首字母是大写的,则该变量是可导出的
  4. 结构体不能嵌套自身的变量,但可以嵌套自身的指针;由此可以实现链表等数据结构;
  5. 空结构体struct{}没有长度,不携带任何信息,可替代map中的bool值,但尽量避免这样用:节约内存很少且语法复杂;
  6. 字面量初始化:var p Point{100, 200}var p Point{x: 100, y:200};但二者不可混用;
  7. 如果变量是不可导出的,则在其它包中,也不能通过隐式初始化该变量;
  8. 结构体变量形参是值引用,想修改或者提高效率,使用指针变量
  9. 快速创建一个结构体指针:pp := &Point{100, 200}
  10. 如果所有成员都是可比较的,那两个结构体变量可以使用==!=来比较;并且此时可以作为map的键;
  11. 使用匿名成员避免类嵌套带来访问上的很多.点运算符,匿名成员只用声明类型,而不用给变量名称;所以也同一类型只能有一个匿名成员
  12. %#v可以输出变量名称;

JSON

  1. encoding/json包提供JSON的序列化与反序列化:Marshal() MarshalIndent() Unmarshal()
  2. 只有可导出的成员才能序列化为JSON
  3. 使用标签来指定序列化的键名称:Position Point json:pos;标签可指定多个,用空格分开;

文本和HTML模板

  1. html/templatetext/template提供一种机制:将程序变量的值代入到文本或者HTML模板中;

  2. 模板中包含一个或多个双大括号包围的单元:{{...}},这称为操作;它是一个表达式,可以选择结构体成员、调用函数和方法、逻辑控制、循环等等;

  3. 操作中的|会将前一个操作的结果当做下一个操作的输入;

  4. 使用report := template.New("name").Funcs(template.FuncMap{"daysAgo": daysAgo}.Parse(templ))来创建模板,使用report.Execute(os.Stdout, data)来输出模板;

  5. 在模板中访问变量:{{.X}},在传入的data数据中需要有X成员,且是可导出的;否则操作不起作用;

  6. html1/template中对于HTML/JS/CSS/URL中的字符串进行自动转义,一次来避免一些安全问题,如注入攻击;

  7. 可以使用template.HTML类型,其中的字符串不会被自动转义,是受信任的字符串类型;

  8. 模板中可以:

    • 声明变量:{{$var := .Name}}
    • 索引:{{$var := index .Foodlist i}}
    • 循环:{{range .Foodlist}} ...{{else}} {{end}},在...部分,使用{{.}}来访问每个元素;
    • 传递结果:{{x | prirntf %v }},会将x放在%v后面;

如有错误 ❌ ,欢迎指正 ☝️~

如有收获 🍗,可以考虑点赞👍/评论💬/收藏⭐️/关注👀,大家共同进步~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值