Go语言学习笔记
文章平均质量分 69
Go语言学习笔记总结。
yunfan188
把时髦的技术挂在嘴边,还不如把过时的技术记在心里。
展开
-
Go语言--编程技巧总结
反射的使用1、对于结构体,我们要输出一个已经初始化的结构体的各个字段的值,可以使用反射来实现。示例如下:package mainimport ( "fmt" "reflect")type Person struct { name string age int gender string city string}func PrintStruct(v interface{}) { types := reflect.Ty原创 2021-07-02 10:17:54 · 174 阅读 · 0 评论 -
Go语言--编程哲学
1 Go语言设计哲学1.1 少即是多Go语言没有犯C++的错误,没有过度地追求语言特性的大而全,而是最大限度地控制语言特性的数量,控制语言使用的复杂性。二八定律在编程语言中可以描述为80%的代码仅使用20%的语言特性。增加语言特性并不能开发效率的提升,原因是它会增加复杂性,导致使用者更容易犯错;有些复杂的语言特性可以通过库的其他形式来辅助支持。所以,在Go语言中,没有看到运算符重载,没有看到多重继承等不太实用的语言特性。少即是多还隐含另一个概念就是语言特性的正交性。几何上的正交指的是两个向量的垂原创 2020-12-04 18:54:39 · 571 阅读 · 0 评论 -
Go语言--包(Package)
1 命名空间和作用域1.1 命名空间命名空间(Namespace)在编程语言中常用来表示标识符(identifier)的可见范围。编程语言借助命名空间来解决标识符不能同名的问题,命名空间实际上相当于给标识符添加了标识前缀,使标识符变得全局唯一。另外,命名空间是程序组织更加模块化,降低了程序内部的耦合性。一个标识符可以在多个命名空间中定义,它在不同命名空间中的含义是不互相干的。新的命名空间中可定义任意的标识符,它们不会与位于其他命名空间上的同名标识符发生冲突,当然自定义标识符尽量不要使用编程语言自原创 2020-12-04 17:25:31 · 3144 阅读 · 1 评论 -
Go语言--编译与工具
1 编译工具Go语言的工具链非常丰富,从获取源码、编译、文档、测试、性能分析,到源码格式化、源码提示、重构工具等应有尽有。 在Go语言中可以使用测试框架编写单元测试,使用统一的命令行即可测试及输出测试报告的工作。基准测试提供可自定义的计时器和一整套基准测试算法,能方便快速地分析一段代码可能存在的CPU耗用和内存分配问题。性能分析工具可以将程序的CPU耗用、内存分配、竞态问题以图形化方式展现出来。1.1 编译(go build)Go语言中使用 go build 命令将.go源码编译为可执行文件。g原创 2020-12-03 17:46:41 · 1693 阅读 · 0 评论 -
Go语言--使用“陷阱2”
1 值、指针和引用<备注> 博文中引用的Go源码基于的Go发布版本:go version go1.15.4 linux/amd64。1.1 传值还是传引用Go语言只有一种参数传递规则,那就是值拷贝,这种规则包括两种含义:(1)函数参数传递时使用的是值拷贝。(2)实例赋值给接口变量,接口对实例的引用是值拷贝。有时明明是值拷贝的地方,结果却修改了变量的内容,有以下两种情况:(1)直接传递的是指针。指针传递同样是值拷贝,但指针和指针副本的值指向的地址是同一个地址,所以能修改原创 2020-11-27 16:05:37 · 286 阅读 · 0 评论 -
Go语言--使用“陷阱1”
Go语言语法简单,类型系统设计得“短小精悍”,但也不是完美无瑕的。Go语言也有一些特性让初学者感到困惑。本篇博客就是逐一介绍Go语言的使用“陷阱”,解除初学者容易犯的错误。Go 语言提供了 go fmt,能够保证代码格式的一致性,在一些代码的书写方式上,Go语言同样有自己的惯用写法,只是这些规则是“潜规则”。1 多值赋值和短变量声明Go语言支持多值赋值,在函数或方法内部也支持短变量声明并赋值,同时Go语言依据类型字面量的值能够自动进行类型推断。1.1 多值赋值可以一次性声明多个变量,并可以在原创 2020-11-26 19:34:34 · 322 阅读 · 0 评论 -
Go语言--反射(reflect)
0 反射的概念反射是指计算机程序在运行时(runtime)可以访问、检测和修改本身状态或行为的一种能力。通俗地将,反射就是程序能够在运行时动态地查看自己的状态,并且允许修改自身的行为。...原创 2020-11-24 14:48:02 · 2054 阅读 · 0 评论 -
Go语言并发编程3 - 并发模型
1 Go的并发机制原创 2020-11-16 17:40:45 · 517 阅读 · 0 评论 -
Go语言并发编程2 - 同步
0 前言Go语言除了可以使用通道进行多个goroutine间数据交换的方式之外,还提供了传统的同步工具。它们都在Go的标准代码包 sync 和 sync/atomic 中,包括原子操作、互斥锁、条件变量以及等待组。1 原子操作原子操作是指执行过程不能被中断的操作。在针对某个值的原子操作执行过程中,CPU绝不会再去执行其他针对该值的操作,无论这些其他操作是否为原子操作。Go语言提供的原子操作都是非侵入式的。它们由标准库代码包 sync/atomic 中的众多API函数实现,我们可以通过调用这些原创 2020-11-12 17:31:09 · 307 阅读 · 2 评论 -
Go语言并发编程1 - 基础
0 并发编程基础并发编程是一种现代计算机编程技术。它的含义比较宽泛,可以是多进程编程、也可以是多线程编程、还可以是编写分布式程序。并发编程思想来源于多任务操作系统,它允许同时运行多个程序。在早起的单用户操作系统中,任务是一个接一个地运行,各个任务的执行完全是串行的。只有在一个任务运行完成之后,另一个任务才会被读取并执行。而多任务操作系统则允许终端用户同时运行多个程序。当一个程序暂时不需要使用CPU时,系统会把该程序挂起或中断,以便其他程序可以使用CPU。而Go语言最明显的优势在于拥有基于多线程的并发编程原创 2020-10-30 18:06:40 · 543 阅读 · 2 评论 -
Go语言--接口的内部实现
1 接口内部实现毫无疑问,接口是Go语言类型系统的灵魂,是Go语言实现多态和反射的基础。前面我们结束了接口的基本概念和用法,定义接口只需要简单声明一个方法集合即可,定义新类型时不需要显式地声明要实现的接口,接口的使用也很简单。但这一切语言特性的背后是语言设计者们的智慧:把复杂留给自己,把简单留给用户。接口的底层是如何实现的?如果实现动态调用?接口的动态调用到底需要多大的额外开销?这是我们需要弄清楚的问题。1.1 数据结构接口变量必须初始化才有意义,没有初始化的接口变量的默认值是nil。具体类原创 2020-10-21 17:10:37 · 559 阅读 · 0 评论 -
Go语言--接口(interface)
0 接口概念接口本身是调用方和实现方均需要遵守的一种协议。接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。Go语言中使用组合实现对象特性的描述。对象的内部使用结构体内嵌组合对象应该具有的特性,对外通过接口暴露能使用的特性。Go语言的设计是非侵入式的设计,也就是说,一个具体类型实现接口不需要在语法上显式地声明,只要具体类型的方法集是接口方法集的超集,就代表该类型实现了接口,编译器在编译时会进行方法集的校验,从而知道哪个类型实现了哪个接口。0.原创 2020-10-19 17:26:24 · 1322 阅读 · 0 评论 -
Go语言--结构体(struct)
0 前言Go语言通过自定义的方式形成新的类型,结构体是类型中都有成员的复合类型。Go语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性。结构体成员是由一系列的成员变量构成,这些成员变量也被称为“字段”。字段有以下特性:字段拥有自己的类型和值。 字段名必须唯一。 字段的类型也可以是结构体,甚至是字段所在结构体的类型。 结构体的存储空间是连续的,字段按照声明时的顺序存放(注意字段之间有字节对齐要求)<提示> Go语言没有“类”的概念,也不支持“类”的继承等面向对象原创 2020-09-30 17:01:25 · 4688 阅读 · 1 评论 -
Go函数--error接口
1 Go语言错误处理思想Go语言的错误处理思想和设计原理包含以下特征:一个可能发生错误的函数,需要返回值中返回一个错误接口(error)。如果函数调用是成功的,错误接口返回 nil,否则返回错误。 在函数调用后需要检查错误,如果发生错误,进行必要的错误处理。<提示> Go语言没有类似Java、.Net中的异常处理机制,虽然可以使用defer、panic、recover模拟,但是官方并不主张这样做。Go语言的设计者认为其他语言的异常机制已被过度使用,上层逻辑需要为函数发生的异常付出太多原创 2020-09-22 19:35:23 · 1020 阅读 · 0 评论 -
Go函数--panic和recover
0 简介panic(宕机) 和 recover(恢复)是Go语言的两个内置函数,这两个内置函数用来处理Go的运行时错误(runtime errors)。panic 用来主动抛出异常,recover 用来捕获panic 抛出的异常。1 基本概念panic 和 recover的函数原型如下:panic(i interface{})recover() interface{}...原创 2020-09-23 16:51:59 · 1576 阅读 · 0 评论 -
Go函数--匿名函数与闭包
0 匿名函数概念Go语言提供两种函数:有名函数和匿名函数。所谓匿名函数就是没有函数名的函数。匿名函数没有函数名,只有函数体。它和有名函数的最大区别是:我们可以在函数内部定义匿名函数,形成类似嵌套的效果。匿名函数常用于实现回调函数、闭包等。1 匿名函数1.1 匿名函数的定义格式func (参数列表) (返回值参数列表) { 函数体}<说明> 匿名函数除了没有函数名外,和普通函数完全相同。1.2 匿名函数的特点1、可以在定义匿名函数的同时直接调用执...原创 2020-09-22 09:50:22 · 616 阅读 · 0 评论 -
Go函数--闭包的内部实现
示例1:package mainimport ( "fmt")func test(x int) func() { fmt.Printf("test.x: &x=%p, x=%d\n", &x, x) return func(){ fmt.Println("closure.x:", &x, x) }}func main(){ f := test(0x100) //fmt.Printf("f type:原创 2020-09-22 15:46:14 · 224 阅读 · 0 评论 -
Go函数--defer语句
1 defer语句该语句用于延迟调用指定的函数,它只能出现在函数或方法的内部,由defer 关键字以及针对某个函数的调用表达式组成。这里被调用的函数称为延迟函数。简单的示例如下:func outerFunc() { defer fmt.Println("函数执行结束前一刻才会被打印") fmt.Println("第一个被打印")}《代码说明》defer关键字后面是针对fmt.Println()函数的调用表达式。这里的outerFunc()称为外围函数。defer语句经常用原创 2020-09-15 15:38:37 · 531 阅读 · 0 评论 -
Go语言--函数(function)
函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段,其可以提高应用的模块性和代码的重复利用率。Go语言支持普通函数、匿名函数和闭包,从设计上对函数进行了优化和改进,让函数使用起来更加方便。...原创 2020-09-17 12:10:43 · 1873 阅读 · 0 评论 -
Go语言--流程控制
0 Go语言流程控制特点Go语言在流程控制方面的特点如下:没有do和while循环,只有一个更广义的for循环。 switch语句灵活多变,还可以用于类型判断。 if语句和switch语句都可以包含一条初始化子语句。 break语句和continue语句可以后跟一条标签(label)语句,以标识需要终止或继续的代码块。 defer语句可以使我们更加方便地执行异常捕获和资源回收工作。 select语句也用于多分支选择,但只与通道配合使用。 go语句用于异步启动goroutine并执行指定.原创 2020-09-14 17:01:56 · 528 阅读 · 0 评论 -
Go容器:列表(list)
0 列表概念列表是一种非连续存储的容器,由多个结点组成,结点之间通过一些变量记录彼此之间的关系。列表有多种实现方法,如单链表、双列表等。在Go语言中,列表的使用是通过 container/list 包来实现的,内部的实现原理是双链表。列表能够高效地进行任意位置的元素插入和删除操作。1 列表的初始化list 的初始化有两种方法:New() 和 声明。两种方法的初始化效果是一致的。1、通过 container/list 包New()方法初始化listvar l = list.New()原创 2020-09-11 22:35:11 · 1111 阅读 · 0 评论 -
Go容器:映射(map)
1 散列表散列表,也称为哈希表,是设计精妙、用途广泛的数据结构之一。它是一个拥有键值对元素的无序集合。在这个集合中,键的值是唯一的,键对应的值可以通过键来获取、更新和删除。无论这个散列表有多大,这些操作基本上是通过常量时间的键比较就可以完成。<提示> 大多数编程语言中映射关系容器使用两种算法:散列表和平衡树。【散列表】散列表可以简单描述为一个“数组”(俗称“桶”),数组的每个元素是一个列表。根据散列函数(也称为哈希函数)获得每个元素的特征值,将特征值作为映射的键。如果特征值重复,原创 2020-09-11 15:11:11 · 401 阅读 · 0 评论 -
Go容器:切片(slice)
1 切片详解1.1 切片概念slice 表示一个拥有相同数据类型元素的可变长度序列。slice 通常写成 [ ]T,其中元素的类型都是 T;因此它看上去像是没有长度限制的数组类型。数组和切片是紧密关联的。slice是一种轻量级数据结构,可以用来访问数组的部分或者全部元素,而这个数组称为slice的底层数组。切片是对数组一个连续片段的引用,因此切片是一个引用类型(类似于Python中的list类型),这个片段可以是整个数组,也可以是由起始和终止索引标识的一个数组子集,需要注意的是,终止索引标识的项原创 2020-09-10 11:19:11 · 617 阅读 · 0 评论 -
Go容器:数组(array)
0 前言变量在一定程度上能满足函数及代码的要求。如果编写一些复杂算法、数据结构和逻辑,就需要更复杂的类型来实现。这类复杂类型一般情况下具有各种形式的存储和处理数据的功能,将它们称为“容器”。1 数组概念数组是一段固定长度的连续内存空间,由若干相同数据类型的元素组成的序列。在Go语言中,数组的大小在声明时就固定下来,使用时可以修改数组的元素,但是数组大小不可变化。1.1 声明数组Go语言数组声明格式如下:var 数组名 [数组长度]T//示例var arr [3]int .原创 2020-09-08 17:50:53 · 299 阅读 · 0 评论 -
Go语言--字符串的使用
一 字符串类型字符串在Go语言中是以原生数据类型出现的,使用字符串就像使用其他基本类型(int、bool、float32、float64等)一样。Go语言中,使用关键字string来声明字符串变量。字符串的值为双引号中的内容,可以在Go语言的源码中直接添加非ASCII码字符。示例代码如下:str := "Hello, Golang"ch := "中文"1.1 字符串转义符Go语言的字符串转义符和其他编程语言的是一样,如:回车、换行、单双引号、制表符等。转义符 含义..原创 2020-09-07 19:23:07 · 2555 阅读 · 0 评论 -
Go语言--数据类型
一 数据类型Go语言中有丰富的数据类型。Go语言按类别有以下几种数据类型:布尔型(bool)布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。<注意>布尔类型变量的默认值为false。 Go 语言中不允许将整型强制转换为布尔型。 布尔型无法参与数值运算,也无法与其他类型进行转换。数字类型数字类型又分为整型、浮点型和其他数字类型。1、整型整型分为有符号整型和无符号整型。2、浮点型floa..原创 2020-09-04 17:02:39 · 475 阅读 · 0 评论 -
Go语言--变量、常量
一、变量1.1 声明变量1、标准格式var变量名变量类型Q:为什么Go语言把数据类型放在后面?答:Go语言这是一种自左向右的声明风格,这种声明的风格的好处是,变量名和类型是完全分隔的。当类型变得复杂时,它的价值就体现出来了。特别类型是函数指针的时候,C语言的声明语法容易让人弄混淆,而Go语言的这种自左向右的声明语法,即使在冗长的声明中也能很清晰地知道整个声明结构。x int //声明变量p *int //声明指针a [3]int ..原创 2020-09-04 10:47:08 · 555 阅读 · 0 评论