Tim

一枚野生程序员~

  • 主页
  • 分类
  • 标签
  • 归档
  • 关于
所有文章 工具

Tim

一枚野生程序员~

  • 主页
  • 分类
  • 标签
  • 归档
  • 关于

Golang的常用容器

阅读数:次 2020-02-16
字数统计: 1.6k字   |   阅读时长≈ 7分

本篇主要是讲述了数组和切片、Map的初始化方式与基本使用、重点阐述了如何使用Map实现Set、用Map实现工厂模式,以及字符串的使用,字符串常用API、Unicode与UTF8的关系!

mark

数组和切片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func TestArray01(t *testing.T)  {
//声明并初始化为默认值
var a [3]int
a[0] = 1

b := [3] int {11, 22, 33}
c := [2][2] int {{11, 22}, {33, 44}}

for _,data := range b{
t.Log(data)
}
for _,data := range c{
t.Log(data)
}
}

func TestArraySection(t *testing.T){
arr := [...]int{11, 22, 33, 44}
arr_sec := arr[:3] //取前三个元素
t.Log(arr_sec)
arr_sec = arr[3:] //取下标为3的后面的所有元素
t.Log(arr_sec)
}

mark

其实切片的内部结构和Buffer的结构是差不多的,切片的使用:

make函数相当于申请空间、并且可以控制多少空间初始化!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package slice_test

import "testing"

func TestSlice(t *testing.T) {
var s0 []int //切片的声明
t.Log(len(s0), cap(s0)) //0 0
s0 = append(s0, 1)
t.Log(len(s0), cap(s0)) //1 1

s1 := []int{1, 2, 3, 4}
t.Log(len(s1), cap(s1)) //4 4

s2 := make([]int, 3, 5)
t.Log(len(s2), cap(s2)) //4 4

s2 = append(s2, 1)
t.Log(len(s2), cap(s2)) //4 4
t.Log(s2[0], s2[1], s2[2], s2[3])
}

切片如何扩容呢?

1
2
3
4
5
6
7
func TestSliceGrowing(t *testing.T)  {
s := []int{}
for i:=0; i<10; i++{
s = append(s, i)
t.Log(len(s), cap(s))
}
}

mark

可以看出来,每次增长二倍的关系,所以就解释了为什么每次append之后都要接收append的返回值,因为go的内部实现就是内存区域Copy的形式,所以随时可能返回新的内存地址,所以需要接收!

mark

1
2
3
4
5
6
7
8
9
10
11
func TestSliceShareMemory(t *testing.T){
year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}

Q2 := year[3:6]
t.Log(Q2, len(Q2), cap(Q2)) //[Apr May Jun] 3 9
summer := year[5:8]
t.Log(summer, len(summer), cap(summer)) //[Jun Jul Aug] 3 7
summer[0] = "UnKnow"
t.Log(Q2, len(Q2), cap(Q2)) //[Apr May UnKnow] 3 9
}

数组和切片的比较:数组不可伸缩、切片可以伸缩;相同维数且相同长度的数组才是可以比较的,切片是不可以比较的,下面的代码会编译不通过:

1
2
3
4
5
6
7
func TestSliceCompare(t *testing.T){
a := []int{1, 2 , 3, 4}
b := []int{1, 2 , 3, 4}
if a == b{ //error
t.Log("equal")
}
}

Map的基本使用

mark

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package map_test

import "testing"

func TestInitMap(t *testing.T) {
m1 := map[string]int{"one":1, "two":2, "three":3}
t.Log(m1, len(m1)) //map[one:1 three:3 two:2] 3

m2 := map[int]int{}
m2[4] = 16
t.Log(m2, len(m2)) //map[4:16] 1

m3 := make(map[int]int, 10)
t.Log(m3, len(m3)) //map[] 0
}

mark

Map的遍历

1
2
3
4
5
6
func TestForEachMap(t *testing.T)  {
m1 := map[string]int{"one":1, "two":2, "three":3}
for k, v := range m1{
t.Log(k, "=", v)
}
}

Map与工厂模式

Map的Value可以是一个方法,因为在Golang中,方法也是一种类型,可以当做参数传递的,与Dock type接口方式一起,可以方便的实现单一方法对象的工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func TestMapWithFunValue(t *testing.T)  {
//Key是整型、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

Go内置集合没有Set实现,可以map[type]bool

1、元素的唯一性

2、基本操作

  • 添加元素
  • 判断元素是否存在
  • 删除元素
  • 元素个数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func TestMapForSet(t *testing.T)  {
mySet := map[int]bool{}
//1、添加元素
mySet[1] = true

//n := 3 //3 is not existing
n := 1 //1 is existing

//2、判断一个元素是否存在
if mySet[n]{
t.Logf("%d is existing", n) //1 is existing
}else{
t.Logf("%d is not existing", n)
}

//3、获取Set的长度
mySet[2] = true
mySet[3] = true
t.Log("len =", len(mySet)) //len = 3

//4、从Set删除元素
delete(mySet, 1)
n = 1
if mySet[n]{
t.Logf("%d is existing", n)
}else{
t.Logf("%d is not existing", n) //1 is not existing
}
}

字符串

与其他主要编程语言的差异:

string 是数据类型,不是引用或指针类型

string 是只读的byte slice, len 函数可以它所包含的byte数

string 的byte数组可以存放任何数据

string实际上就是一个不可变的切片

1
2
3
4
5
6
7
8
9
10
11
12
func TestString(t *testing.T)  {
var s string
t.Log(s) //初始化默认值""
s = "hello"
t.Log(len(s))

//s[3] = 'c' error string不可变
s = "\xE4\xB8\xA5" //可以存储任意二进制数据
t.Log(s, len(s)) //严
s = "中国"
t.Log(len(s)) //len求的是字节数
}

Unicode与UTF8

1、Unicode是一种字符集(code point)

2、UTF8是Unicode的存储实现(转为字节序列的规则)

Unicode为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF(十六进制),有110多万,每个字符都有一个唯一的Unicode编号,这个编号一般写成16进制, Unicode就相当于一张表,建立了字符与编号之间的联系,而UTF8是具体实现, 在UTF8中编号小的使用的字节就少,编号大的使用的字节就多。使用的字节个数从1到4个不等。

rune函数

在Go当中 string底层是用byte数组存的,并且是不可以改变的。fmt.Println(len(“Go编程”)) 输出结果应该是8因为中文字符是用3个字节存的, len(string(rune(‘编’)))的结果是3 ,如果想要获得我们想要的情况的话,需要先转换为rune切片再使用内置的len函数: fmt.Println(len([]rune(s))) 结果就是4了。 所以用string存储unicode的话,如果有中文,按下标是访问不到的,因为你只能得到一个byte。 要想访问中文的话,还是要用rune切片,这样就能按下标访问。

1
2
3
4
5
6
7
8
9
func TestString(t *testing.T)  {
s := "中"
t.Log(len(s)) //3

c := []rune(s)

t.Logf("中 unicode %x", c[0]) //中 unicode 4e2d
t.Logf("中 UTF8 %x", s) //中 UTF8 e4b8ad
}

mark

常用的字符串处理函数:
strings包:
https://golang.org/pkg/strings

strconv包
https://golang.org/pkg/strconv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func TestStringFunc(t *testing.T)  {
//切割字符串
s := "A,B,C"
split := strings.Split(s, ",")
for _, ch := range split{
t.Log(ch)
}

//连接字符串数组的元素
t.Log(strings.Join(split, "-"))

//字符串与数字的转换
s = strconv.Itoa(250)
t.Logf("s = %s", s)

num := "100"
//返回两个值,err代表是否发生错误
if i, err := strconv.Atoi(num); err == nil{
t.Log(100 + i)
}
}
赏

谢谢你请我喝咖啡

支付宝
微信
  • 本文作者: Tim
  • 本文链接: https://zouchanglin.cn/761533839.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!
  • Golang
  • 编程语言

扫一扫,分享到微信

Golang值得注意的点
IDEA插件推荐
  1. 1. 数组和切片
  2. 2. Map的基本使用
  3. 3. Map与工厂模式
  4. 4. Map实现Set
  5. 5. 字符串
  6. 6. Unicode与UTF8
© 2017-2021 Tim
本站总访问量次 | 本站访客数人
  • 所有文章
  • 工具

tag:

  • 生活
  • Android
  • 索引
  • MySQL
  • 组件通信
  • Nginx
  • JavaSE
  • JUC
  • JavaWeb
  • 模板引擎
  • 前端
  • Linux
  • 计算机网络
  • Docker
  • C/C++
  • JVM
  • 上传下载
  • JavaEE
  • SpringCloud
  • Golang
  • Gradle
  • 网络安全
  • 非对称加密
  • IDEA
  • SpringBoot
  • Jenkins
  • 字符串
  • vim
  • 存储
  • 文件下载
  • Mac
  • Windows
  • NIO
  • RPC
  • 集群
  • 微服务
  • SSH
  • 配置中心
  • XML
  • Chrome
  • 压力测试
  • Git
  • 博客
  • 概率论
  • 排序算法
  • 分布式
  • 异常处理
  • 文件系统
  • 哈希
  • openCV
  • 栈
  • 回溯
  • SpringCore
  • 流媒体
  • rtmp
  • 面向对象
  • Vue
  • ElementUI
  • 软件工程
  • 异步
  • 自定义UI
  • ORM框架
  • 模块化
  • 交互式
  • Jsoup
  • Http Client
  • LRUCache
  • RabbitMQ
  • 消息通信
  • 服务解耦
  • 负载均衡
  • 权限
  • 多线程
  • 单例模式
  • Protobuf
  • 序列化
  • Python
  • m3u8
  • 堆
  • 二叉树
  • 自定义View
  • 观察者模式
  • 设计模式
  • 线程池
  • 动态扩容
  • 高可用
  • GC
  • ffmpeg
  • SpringMVC
  • REST
  • Redis
  • 缓存中间件
  • UML
  • Maven
  • Netty
  • 高性能网络
  • IPC通信
  • IO
  • Stream
  • 发布订阅
  • SQLite
  • Hash
  • 集合框架
  • 链表
  • Lambda
  • 汇编语言
  • 组件化
  • Router
  • 开发工具

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia-plus根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 思维导图
  • PDF工具
  • 无损放大
  • 代码转图
  • HTTPS证书