如何优雅的写出Go程序代码
文章平均质量分 77
面向加薪学习
这个作者很懒,什么都没留下…
展开
-
21 面试必问!Goroutine的调度原理
正常的执行顺序就是线性的,谁在前面,谁就先执行,但是并发能力,会让你的程序,可以由若干个代码片段组合而成,并且每个片段都是独立运行的。Go语言天生支持这种并发能力,而Goroutine就是Go原生支持并发的具体实现。无论是Go的运行时还是用户写的代码都是运行在Goroutine中。Goroutine是由Go运行时管理的轻量级线程。和操作系统线程相比,goroutine的资源占用和使用代价非常小。我们可以创建几百到十几万个goroutine,甚至更多。Go运行时负责对goroutine进行管理和调度。不要原创 2021-01-21 14:13:40 · 542 阅读 · 0 评论 -
13 理解包导入路径的含义
Go 语言是使用包(package)作为基本单元来组织源码的, Go 程序就是这些包链接起来而构建的。 与C 语言的头文件包含机制相比则是“先进”了许多。即便是每次编译都是从头开始。避免了 C 语言那种通过头文件分析依赖的巨大开销。Go 语言以包为基本构建单元的构建模型,依赖分析非常简单。一 构建过程Go 编译速度快从三个方面分析:1.Go 要求每个源文件在开头处显式地import所有依赖的包,Go编译器不必读取和处理整个文件就可以确定其依赖的包列表;2.Go 要求包之间不能存在循环依赖。由于无环原创 2021-01-21 13:51:08 · 243 阅读 · 0 评论 -
19 小接口的妙用
1 Go推荐的”小接口"接口interface这个单词,其实翻译过来就是 契约。契约可以简单也可以复杂,Go语言选择了简单。1) Go语言的接口与实现子类是隐式的关系,不是像java语言那样,要显示的implements关键字实现,实现类只要实现接口中的方法集合的全部方法,就是自动实现了该接口。2) 小接口使用起来更加灵活。下面是标准库中的定义// $GOROOT/src/builtin/builtin.gotype error interface { Error() string}原创 2021-01-20 06:53:02 · 143 阅读 · 0 评论 -
20.不要在函数参数中使用空接口
为什么要做这一节,有一些小伙伴,把一些代码给我看,说同时写了的代码,参数是interface{}空接口,看不懂,不知道是做什么的,那么我们下面就看看空接口当参数的是不是合适?// $GOROOT/src/io/io.gotype Reader interface { Read(p []byte) (n int, err error)}Go编译器通过分析该接口定义得到接口的名称信息以及其方法信息,此接口类型参数赋值时,编译器会根据这些信息对实参进行检查。如果函数或方法的参数类型为空接原创 2021-01-20 06:53:46 · 131 阅读 · 0 评论 -
18 接口-实现方法集合
1. 方法集合func ShowMethod(i interface{}) { v := reflect.TypeOf(i) elemTyp := v.Elem() n := elemTyp.NumMethod() if n == 0 { fmt.Printf("%s's 方法为空!\n", elemTyp) return } fmt.Printf("%s's 方法:\n", elemTyp) for j := 0原创 2021-01-20 06:52:33 · 153 阅读 · 0 评论 -
17. Go语言---方法是什么
方法声明func(接受者 类型/类型指针) 方法名(参数列表)(返回值列表{//方法体}通过接收者,上述方法被绑定到某个类型上了。上述方法就是类型的一个方法,通过类型或类型指针的实例调用该方法。var t Tt.MethodName(参数列表)var pt *T = &tpt.MethodName(参数列表)方法名首字母大写巨鼎是导出方法(公开的)方法名定义要和类型定义放在同一个包中。func (t T) X1() 等价 X1(t T)当接收者类型为T的时候,Go函数的参数原创 2021-01-20 06:52:02 · 113 阅读 · 0 评论 -
16.defer 让代码更清晰
一 defer是什么日常我们写如下的代码var mu sync.Mutexmu.Lock()count++mu.Unlock()这样的代码特点就是在函数中会申请一些资源并在函数退出前释放或关闭资源。函数的实现需要资源在函数退出时被及时地释放,无论函数的执行时按预期进行,还是抛错。为此,程序员需要对函数中的错误里特别关注,在错误处理时不能忘记释放资源。这样让程序员需要思考的问题就会增加。同时多个资源释放怎么办?多个资源抛错怎么办?这样的逻辑将变得十分复杂,代码可读性也会极大降低,那程序的健壮性也原创 2021-01-20 06:51:22 · 125 阅读 · 0 评论 -
15 Go语言:函数是“一等公民“
m *sync.Mutexm.Lock() ...m.Unlock()如果要改变共享变量的情况下,我们会使用lock和unlock方法。在函数退出时被及时正确地释放,无论函数的执行流是按预期顺利进行还是出现错误。1. defer 的运作机制只有在函数(和方法)内部才能使用 defer。 defer 关键字后面只能接函数(或方法),这些函数被称为 deferred 函数。defer 将它们注册到其所在 goroutine 用于存放 deferred 函数的栈数据结构中,这些 defer原创 2021-01-20 06:50:36 · 177 阅读 · 0 评论 -
14.init你用对了吗?
在 Go 语言中,通过包的 init 函数来完成初始化的工作。1. init 函数Go 语言中有两个特殊的函数:1) main 包中的 main 函数,它是所有 Go 可执行程序的入口函数;2) 包级别的 init 函数。init 函数是一个无参无返回值的函数:func init() { ...}如果一个包定义了 init 函数,Go 运行时会负责在该包初始化时调用它的 init 函数。我们不能显式调用 init,否则会在编译期间报错。一个 Go 包可以拥有多个 ini原创 2021-01-20 06:49:31 · 529 阅读 · 0 评论 -
12.Go 字符串
内置的 string 类型。无论是字符串常量、字符串变量还是出现的字符串字面值,都被统一设置为 string。const ( s = “Hello")func main() { var s1 string = “Golang" fmt.Printf("%T\n", s) // string fmt.Printf("%T\n", s1) // string fmt.Printf("%T\n", “Cool Golang"原创 2021-01-20 06:49:04 · 101 阅读 · 0 评论 -
11.深入理解切片(slice)
slice是 Go 语言在数组之上提供的一个重要的抽象数据类型。在绝大多数需要使用数组的场合,切片都实现了完美替代。并且和数组相比,切片提供了更通用、功能更强大且便捷的数据序列访问接口。1.什么是数组Go 语言数组是一个固定长度的、容纳同构类型元素的连续序列。因此 Go 数组类型具有两个属性:元素类型和数组长度。但凡这两个属性相同的数组类型是等价的。比如下面变量 a、b、c 对应的数组类型是三个不同的数组类型:var a [8]stringvar b [8]bytevar c [9]string原创 2021-01-20 06:48:11 · 856 阅读 · 0 评论 -
10.零值可用
1. Go 类型的零值当通过声明或调用new为变量分配存储空间,或者通过复合文字字面量或make调用创建新值,并且还不提供显式初始化的情况下,Go会为变量或值提供默认值。Go 语言的每种原生类型都有其默认值,这个默认值就是这个类型的零值。内置零值如下:所有整型类型:0浮点类型:0.0布尔类型:false字符串类型:""指针、interface、slice、channel、map、function:nil数组、结构体等类型的零值初始化就是对其组成元素逐一进行零值初始化。2. 零值可用例子原创 2021-01-19 20:05:03 · 126 阅读 · 0 评论 -
09.枚举常量
iota 是 Go 语言提供的预定义标识符,它表示的含义是 const 声明块(包括单行声明)中每个常量所处位置在块中的偏移量(从零开始)。同时,每一行中的 iota 自身也是一个无类型常量。// $GOROOT/src/sync/mutex.goconst ( mutexLocked = 1 << iota // iota 的值是在 const 块中的偏移,因此 iota 的值为 0,我们得到 mutexLocked 这个常量的值为 1 <<原创 2021-01-19 20:00:24 · 213 阅读 · 0 评论 -
08.无类型常量
1. Go 常量使用常量定义的关键字const。Go 中所有与常量有关的声明都使用const。// $GOROOT/src/os/file.goconst ( // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified. O_RDONLY int = syscall.O_RDONLY // open the file read-only. O_WRONLY int = syscall.O_WRONLY //原创 2021-01-19 19:57:21 · 170 阅读 · 0 评论 -
07.变量声明须一致
Go 语言,使用变量之前需要先进行变量的声明。var s string = “Golang"n := 666Go 语言有两类变量包级别(package varible):在 package 级别可见的变量。如果是导出变量,该变量也可以被视为全局变量;局部变量(local varible):函数或方法体内声明的变量,仅在函数或方法体内可见。1. 包级别变量包级变量使用var 关键字的变量声明形式,从变量声明的时候是否延迟初始化这个角度对包级变量进行一次分类。1). 声明并同时显式初始化 /原创 2021-01-19 19:52:09 · 547 阅读 · 0 评论 -
06.命名惯例-见名知意
日常工作中,命名这件事看似简单,如果在大规模软件开发中,做出好的命名并非易事。命名是编程语言的要求:好的命名是为了提高程序的可读性和可维护性。什么是好的命名呢?无论哪门编程语言,良好的命名应该遵循一些通用的原则,不同编程语言在命名上还会有一些个性化的命名习惯。要想做好 Go 标识符命名(包括 package 命名),最少要遵循两个原则:1 简单且一致2 利用上下文辅助命名1. 简单且一致对于简单,我们最直观地理解就是越短越好,但这里的简单还包含着清晰明确。短意味着能用一个单词命名的,就不要使用单原创 2021-01-19 13:13:51 · 911 阅读 · 0 评论 -
05.Go代码风格的唯一标准
gofmtGo 语言设计的目标之一就是解决大型软件系统的大规模开发的问题,解决大型团队的开发问题,Go 核心团队给它起了一个名字叫:规模化(scale)。gofmt 是伴随着 Go 语言诞生的第一批在“规模化”这个目标上的实践和尝试。gofmt 将统一的代码风格内化到 Go 语言之中,并和 Go 语言一起推广给所有 Go 开发者。在一致的代码风格下,Go 开发人员阅读和维护他人代码时,效率大幅。gofmt 代码风格已经成为 Go 开发者的一种共识。如果你是Go 开发人员,提交代码前使用 gofmt 格式原创 2021-01-19 13:02:33 · 122 阅读 · 0 评论 -
04.Go项目布局-你如何设计项目结构
Go 语言典型项目结构在多年的 Go 语言实践积累后逐渐形成了一种典型项目结构,如下图所示:上面就是一个支持构建二进制可执行文件(在 src 下)的典型 Go 项目的结构。1 src 目录:存放项目要编译构建的可执行文件对应的 main 包的源文件。如果有多个可执行文件需要构建,每个可执行文件的 main 包单独放在一个子目录中,比如图中的 appA、appB;src 目录下的各 app 的 main 包将整个项目的依赖连接在一起。我们在 main 包中会做一些命令行参数解析、资源初始化、日志设施原创 2021-01-19 09:04:40 · 360 阅读 · 0 评论 -
03.Go语言的设计哲学之三: 并发
Go 语言原生并发原则1) Go 语言自身实现层面支持面向多核硬件的并发执行和调度提到并发执行与调度,我们首先想到的就是操作系统对进程、线程的调度。操作系统调度器会将系统中的多个线程按照一定算法调度到物理 CPU 上去运行。传统的编程语言比如 C、C++ 等的并发实现实际上就是基于操作系统调度的,即程序负责创建线程(一般通过 pthread 等函数库调用实现),操作系统负责调度。这种传统支持并发的方式有诸多不足:复杂1 创建容易,退出难:使用 C 语言的开发人员都知道,创建一个 thread(比原创 2021-01-19 08:50:15 · 170 阅读 · 0 评论 -
02.Go语言的设计哲学之二: 组合
Java 、C++等主流面向对象(以下简称 OO)语言通过复杂和庞大的、自上而下的类型体系、继承、显式接口实现等机制将程序的各个部分耦合起来,但在 Go 语言中我们找不到经典 OO 的语法元素、类型体系和继承机制,或者说 Go 语言本质上就不属于经典 OO 语言范畴。针对这种情况,很多人会问:那 Go 语言是如何将程序的各个部分有机地耦合在一起的呢?Go 语言遵从的设计哲学也是组合。在介绍组合之前,我们可以先来了解一下 Go 在语法元素设计时是如何为组合哲学的应用打下坚实基础的。在 Go 语言设计层面,原创 2021-01-19 08:22:20 · 310 阅读 · 0 评论 -
01.Go语言的设计哲学之一:简单
这里写自定义目录标题01.Go语言的设计哲学之一:简单第一条原则: 简单,少即是多01.Go语言的设计哲学之一:简单Go 语言从诞生到今天已经有十年多了,Go 语言的魅力使得其在全世界范围内拥有了百万级的支持用户。那究竟是什么让大量的开发人员学习 Go 或从其他语言转向 Go 语言呢?根源就在于 Go 语言的设计哲学。关于 Go 语言的设计哲学,Go 语言之父们以及 Go 核心团队的开发者们并没有给出明确的官方说法。但在这里我将根据我个人对他们以及 Go 社区主流观点和代码行为的整理、分析和总结,列出原创 2021-01-19 08:10:38 · 226 阅读 · 0 评论