Go 语言编程模式实战
陈皓
网名“左耳朵耗子”,资深技术专家
21556 人已学习
免费领取
Go 语言编程模式实战
15
15
1.0x
00:00/00:00
登录|注册

01 | Go编程模式:切片、接口、时间和性能

你好,我是陈皓,网名左耳朵耗子。
今天是我们的第一节课,我先带你学习下 Go 语言编程模式的一些基本技术和要点。了解了这些内容,你就可以更轻松地掌握 Go 语言编程了,其中主要包括数组切片的一些小坑、接口编程,以及时间和程序运行性能相关的内容。
话不多说,我们直接开始。

Slice

首先,我来介绍下 Slice,中文翻译叫“切片”,这个东西在 Go 语言中不是数组,而是一个结构体,其定义如下:
type slice struct {
array unsafe.Pointer //指向存放数据的数组指针
len int //长度有多大
cap int //容量有多大
}
一个空的 Slice 的表现如下图所示:
熟悉 C/C++ 的同学一定会知道在结构体里用数组指针的问题——数据会发生共享!下面我们来看看 Slice 的一些操作:
foo = make([]int, 5)
foo[3] = 42
foo[4] = 100
bar := foo[1:4]
bar[1] = 99
我来解释下这段代码:
首先,创建一个 foo 的 Slice,其中的长度和容量都是 5;
然后,开始对 foo 所指向的数组中的索引为 3 和 4 的元素进行赋值;
最后,对 foo 做切片后赋值给 bar,再修改 bar[1]。
为了方便你理解,我画了一张图:
从这张图片中,我们可以看到,因为 foo 和 bar 的内存是共享的,所以,foo 和 bar 对数组内容的修改都会影响到对方。
接下来,我们再来看一个数据操作 append() 的示例:
a := make([]int, 32)
b := a[1:16]
a = append(a, 1)
a[2] = 42
在这段代码中,把 a[1:16] 的切片赋给 b ,此时,ab 的内存空间是共享的,然后,a 做了一个 append()的操作,这个操作会让 a 重新分配内存,这就会导致 ab 不再共享,如下图所示:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了Go编程模式中的一些基本技术和要点。首先讨论了切片(Slice)的定义和操作,包括共享内存的问题和`append()`函数的使用。接着介绍了深度比较的方法,使用了反射`reflect.DeepEqual()`函数。然后探讨了接口编程,包括使用“Receiver”和接口的抽象使用。此外,文章还提到了接口完整性检查的方法,以及时间处理的重要性和使用建议。总的来说,本文涵盖了Go语言编程中的一些基本技术和要点,适合想要了解Go语言编程模式的读者阅读。 此外,文章还提供了一些关于Go语言性能的提示,包括数字转换、内存分配、字符串拼接、并发操作、内存重用、I/O缓冲、正则表达式编译、协议选择等方面的建议。这些提示可以帮助读者写出更高效的Go代码,提升程序性能。总的来说,本文内容丰富,既介绍了Go编程模式,又提供了实用的性能优化建议,适合对Go语言编程感兴趣的读者阅读。

该试读文章来自《Go 语言编程模式实战》,如需阅读全部文章,
请先领取课程
免费领取
登录 后留言

全部留言(22)

  • 最新
  • 精选
  • 姜姜
    老师,关于slice的例子中,第三和第四张配图画的有问题。 第三张图,"a := make([]int, 32) b := a[1:16]",这里切片b的cap应该是31,图中b的cap是15。 第四张图,切片dir2的len和cap都应该是9,而不是图中的10. 当然,这几个值并不影响示例所讲的内容,只是在看图的时候容易让人困惑。
    2021-01-09
    2
    15
  • helloworld
    type Shape interface { Sides() int Area() int } type Square struct { len int } func (s* Square) Sides() int { return 4 } func main() { s := Square{len: 5} fmt.Printf("%d\n",s.Sides()) } 文章中这段本来就能跑通,和接口Shape没有任何关系吧,如果想和接口Shape扯上关系,可以先定义接口变量再赋值啊,比如: var s Shape s = Square{len: 5} 这样赋值就会报错提示没有实现接口了。 所以感觉文中这个例子举的不太恰当,不知道我理解的对不对,望指正~
    2021-01-24
    5
    9
  • 盖瑞Chen
    coolshell上都有,但,访问coolshell实在太难
    2021-01-10
    4
  • 向往
    干货满满,有些知识的确受益非浅,比如切片扩容提前配置好容量。
    2021-01-09
    3
  • neohope
    皓哥好,感觉这个切片的内存共享方式真的好诡异,对比于内存在写时拷贝,这个内存算是“扩容时拷贝了吧”?这个感觉很容易出错。 您觉得语言设计者为何会做这样的设计呢?这个功能主要是和什么便利做了折中考虑呢?说实话感觉还不如指针靠谱
    2021-03-10
    1
    2
  • roseduan
    感谢耗子叔的分享,我把文中的代码整理了一下,放到了我的 github 上,给有需要的朋友,地址:https://github.com/roseduan/go-patterns
    2021-01-30
    1
    2
  • 橙子888
    感谢耗子叔的分享,受益良多。
    2021-01-08
    2
  • 杨学者
    大佬已乘黄鹤去,此地空余小菜鸡。黄鹤一去不复返…
    2023-05-30归属地:上海
    2
  • Daiver
    看了第二遍,受益匪浅
    2021-02-05
    1
  • 小匚
    来看看为什么说 Go 的性能优于 Python😃
    2021-01-09
    2
    1
收起评论
显示
设置
留言
22
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部