最佳实践
1 包管理
1.1 使用包管理对Golang项目进行管理,如:godep/vendor等工具
1.2 main/init函数使用,init函数参考python
1.2.1 main->import->const->var->init
1.2.2 同一个package属于一个作用域,所以不要重复定义变量等
1.3 万能的type
1.3.1 type ages int type money float32 type months map[string]int 定义新类型
1.3.2 type testInt func(int) (bool) // 声明了一个函数类型
1.3.3 type person struct //声明一个结构体类型
1.3.4 type PeopleProtocol interface //声明一个接口类型
1.4 万能的函数
1.4.1 面向函数编程
1.4.1.1 数据作为参数传递给函数形参
1.4.2 面向对象编程
1.4.2.1 通过带有接受者函数实现,使用起来函数作为了对象的属性
1.4.2.2 golang可以自动匹配接受者的类型,不管是对象还是对象的指针
1.4.2.3 字段继承通过匿名字段实现;方法继承/重写也通过匿名字段实现
1.4.3 面向接口编程
1.4.3.1 接口定义协议,通过带接受者的函数实现接口,实现了接口的对象可以被接口引用
1.4.3.2 面向接口不是对面向对象的否定,它是面向对象编程体系中的思想精髓之一
1.4.3.3 面向接口编程的本质是面向协议编程,只要实现了该协议,不管什么对象都是可以随时替代的,可以提高软件的灵活性与可维护性opic
1.4.3.4 面向对象是为了实现代码复用,面向接口是为了实现多态、实现标准定制、灵活替代
2 交叉编译
2.1 使用交叉编译工具或者使用Golang指定目标编译
2.2 windows
2.2.1 apt-get install gcc-mingw-w64 env CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build -o ./app/app.exe ./app/main.go env CGO_ENABLED=1 GOOS=windows GOARCH=386 CC=i686-w64-mingw32-gcc go build -o ./app/app.exe ./app/main.go
3 错误处理
3.1 官方推荐
3.1.1 error也是值,并且需要总是检查error并对其处理
3.1.2 慎用或者不使用panic等手段
3.2 其他推荐
3.2.1 使用第三方errors库
3.2.2 模仿Web开发模式,子模块只管抛出异常,并在全局位置捕获异常统一处理,即使用panic、recover、defer等联合进行处理
3.2.3 defer参数值是在声明时确定,而不是在调用时才确定
4 数据类型
4.1 变量与常量
4.1.1 全局变量使用var声明,内部变量尽量使用简短方式声明/定义,需要明确指定变量类型的除外
4.1.2 常量可以指定为数值、布尔值或字符串等类型,格式:const constantName = value
4.1.3 同时声明多个常量、变量,或者导入多个包时,可采用分组的方式进行声明,适用于import/const/var
4.2 默认类型与默认值
4.2.1 整型、浮点型、复数默认类型分别为int/float64/complex128
4.2.2 默认值
4.2.2.1 bool-false, string-"", 整型、浮点型、复数-0
4.2.2.2 枚举使用iota进行0值重置
4.2.2.3 array需要指定长度,讨论其默认值没有意义
4.2.2.4 初始声明未初始化的slice/map默认为nil
4.2.3 初始化
4.2.3.1 声明初始化、make/new初始化、赋值初始化
4.3 值类型
4.3.1 基本类型
4.3.1.1 rune-int32, int8, int16, int32-int, int64和byte-uint8, uint8, uint16, uint32, uint64
4.3.1.2 uintptr, intptr指针类型,用于指针操作
4.3.1.3 rune是int32的别称,byte是uint8的别称
4.3.2 字符串
4.3.2.1 字符串连接使用+运算符或者使用fmt格式化返回字符串
4.3.2.2 字符串为不可变类型,如果需要改变字符串值,需要转化为[]byte/[]rune切片进行操作
4.3.2.3 字符串使用UTF-8编码存储,如果需要按照Unicode方式进行操作,需要转化为[]rune切片或者使用"unicode/utf8"包
4.3.3 数组array
4.3.3.1 定义数组必须指定长度,且数组长度定义之后不能改变
4.3.3.2 数组赋值为值的赋值,参数传递也是值传递,即实参数组赋值一份数据给形参数组
4.3.4 结构体struct
4.3.4.1 struct与array一样是值类型,作为参数会copy完整数据;slice、map、channel等传递的是数据的内存地址
4.3.4.2 struct不能使用make初始化,可以使用声明方式或者new返回指针的方式初始化
4.3.4.3 通过非匿名字段实现对象的包含与持有,通过匿名字段实现传统的类的继承关系
4.3.4.4 与面向对象语言不同的是子类struct不能赋值给父类struct,即struct可以模拟面向对象,但不是为了实现完全的面向对象
4.3.4.5 字段继承通过匿名字段实现;方法继承/重写也通过匿名字段实现
4.3.4.6 与传统面向对象不同的是,golang中子类对象不能赋值给基类对象
4.4 引用类型
4.4.1 map、channel、slice为引用类型 如果两个引用类型同时指向一个底层,那么一个改变,另一个也相应的改变 三者都可以通过for...range遍历
4.4.2 切片slice
4.4.2.1 定义slice不指定长度,使用make可以指定长度
4.4.2.2 慎用append函数改变slice的长度,可能会异常改变被引用的数组内容,这可能是我们并不期望的结果
4.4.2.3 slice底层使用struct实现,slice的cap大小由golang动态实现
4.4.2.4 slice初始化,要么引用其他数组/切片,要么使用make/new初始化,make初始化可以指定初始大小
4.4.3 哈希map
4.4.3.1 定义map不需要指定长度,通过make指定长度也没有意义,map本来就是动态的,即使指定长度没有数据就认为len为0
4.4.3.2 map和其他基本型别不同,它不是thread-safe,在多个go-routine存取时,必须使用mutex lock机制
4.4.3.3 GET MAP两个返回值, v, ok := mapa["C"], 如果不存在则ok为false
4.4.4 make与new
4.4.4.1 make用于内建类型(map、slice 和channel)的内存分配。new用于各种类型的内存分配
4.4.4.2 new返回指针, 且值为 nil; new(T)分配了零值填充的T类型的内存空间,并且返回其地址
4.4.4.3 make返回对象, 且值不为nil; make返回初始化后的(非零)值
4.4.5 channel
4.4.5.1 golang并发本质
4.4.5.1.1 PMG的原理,P对应操作系统进程--对程序的抽象,W对应操作系统线程--对寄存器的抽象, G对应goroutine--go实现的轻量级线程,也即GreenThreads用户态线程。 一句话,golang提供了用户态线程的管理机制。
4.4.5.1.2 G通过阻塞方式调用,M不会阻塞,G通过netpoller唤醒。一句话,用户态线程通过netpoller方式避免阻塞系统线程。 当然,其他可能阻塞的地方golang的runtime也会做相应的优化,比如for循环也会被runtime优化。
4.4.5.1.3 goroutine+channel的本质是对生产车间流水线的完美模拟,应用开发者只要想清楚流水线该如何设计之后就能轻易理解 goroutine/channel的精妙,gorotine相当于很多干活的人,chennel相当于很多人之前的连线,点和线之间就可以设计复杂的工作流 理解了这一点就可以将问题抽象为,这个活儿能不能多个人一起干(多个goroutine), 这多个人怎么使用(chennel)有效的组织起来形成流水线?
4.4.5.2 无缓冲的channel可用于在多个goroutine之间同步,避免了显示的加锁。需要多个goroutine存在才能跑起来,只有一个goroutine会造成死锁
4.4.5.3 有缓冲的channel是对无缓冲channel的补充,可以作为流水线缓冲队列使用,一定程度上可以减轻无缓冲channel即阻塞式channel的压力,提高流水线的整体性能
4.4.5.4 等待所有routine完成 需要考虑解决两个问题
4.4.5.4.1 使用channel同步等待、使用sync.WaitGroup等待、主线程开goroutine等待并发出done信号,单个worker作为主goroutine
4.4.5.4.2 需要安全关闭channel
4.4.5.4.2.1 单worker输出的channel可以由生产者主动关闭
4.4.5.4.2.2 多worker输出的channel可以由第三方主动关闭,但要确认不会出现PANIC
4.4.5.4.2.3 下游goroutine使用for-range等待channel关闭
4.4.5.4.2.4 worker中select监控多个channel数据流动,接收done信号
4.4.5.4.2.5 最佳实践参考
4.4.5.4.2.5.1 可以在worker函数内部自定义out channel
4.4.5.4.2.5.2 worker函数需要保证goroutine结束之后关闭out channel
4.4.5.4.2.5.3 worker函数如果有多个in channel,可以使用WaitGroup,等待所有in处理完毕之后关闭out
4.4.5.4.2.5.4 使用done channel close信号通知所有上游goroutine
4.4.5.4.2.5.5 最终消费者/主goroutine总是检查out是否被关闭
4.4.5.4.2.6 总结
4.4.5.4.2.6.1 当所有发送操作结束时,每个阶段都关闭自己的 outbound channels
4.4.5.4.2.6.2 每个阶段都会一直从 inbound channels 接收数据,直到这些 channels 被关闭,或发送者解除阻塞状态
4.5 其他
4.5.1 function
4.5.1.1 支持多返回值与变参,总是命名返回值,可以直接return
4.5.1.2 值类型(array/struct)为传值调用--参数赋值,引用类型(channel/map/slice,指针等)为传递地址调用--参数引用
4.5.1.3 值传递&引用传递
4.5.1.3.1 传值与传址本质都是copy操作,一个copy数据,一个copy地址, copy数据不能改变实参,copy地址通过指针操作可以一定程度上改变实参的值, 但肯定不是随意改变,比如append操作就不会改变原始实参
4.5.1.3.2 Go语言中channel,slice,map这三种类型的实现机制类似指针,所以可以直接传递,而不用取地址后传递指针 若函数需改变slice的长度(比如进行append操作),则仍需要取地址传递指针
4.5.1.3.3 函数参数中存在此概念,带有接受者的函数也区分值传递与引用传递,也存在此概念
4.5.1.3.4 闭包通过非参数传递的方式直接引用外层代码定义的变量,传递的是变量的地址
4.5.1.4 函数本身也可以作为类型,或者作为值传递给其他函数的形参,比如多种类型过滤器filter的实现即可参考这种模式
4.5.1.5 带有接收者的函数即可实现面向对象--方法的继承/重写 虽然method的名字一模一样,但是如果接收者不一样,那么method就不一样
4.5.1.6 struct、type自定义类型等都可以作为接受者
4.5.2 interface
4.5.2.1 接口A定义-B对象实现-C对象继承B对象属性-C也就继承了B对象的接口/可以重写-->类的继承、方法的继承、多态的实现
4.5.2.2 子类对象不能赋值给父类对象,但是接口可接受任意实现了该接口的对象,请注意这两点与传统面向对象设计语言的区别
4.5.2.3 任何对象都可以赋值给空interface,即可以存储任意类型对象,类似于C语言的 C语言的void*
4.5.2.4 像Java一样,接口也是可以通过extends继承的
4.5.2.5 反射
4.5.2.5.1 golang的反射与Java相比功能弱很多,golang不支持解析string然后执行
4.5.2.5.2 golang的反射机制只能存在于已经存在的对象/类型上面
4.5.2.5.3 如果要实现与Java一样的反射(RPC/Web框架)机制, 需要先把字符串和类的reflect.Typeof关联好,然后根据字符串找到对应的类型,用reflect.New构造对象就可以了 即需要提前有注册机制进行字符串<-->类型的关联映射
5 流程控制
5.1 if 代码块内允许声明临时变量在if-else代码块内使用,使用分号;分割多条语句
5.2 for 既可以用来循环读取数据,又可以当作while来控制逻辑,还能迭代操作,Golang中没有while操作符 在嵌套For循环中,将循环次数多的循环放在内侧,循环次数少的循环放在外侧,其性能会提高 减少循环变量的实例化,其性能也会提高
5.3 switch 默认在case之后带 break,如果需要继续遍历,可以使用fallthrough强制执行后面的case代码
5.4 break, continue, return, goto 与 C 语言实现一样
 
 

【GoLang】golang 最佳实践汇总的更多相关文章

  1. Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践

    目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ?   RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...

  2. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目

    Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...

  3. Golang - 爬虫案例实践

    目录 Golang - 爬虫案例实践 1. 爬虫步骤 2. 正则表达式 3. 并发爬取美图 Golang - 爬虫案例实践 1. 爬虫步骤 明确目标(确定在哪个网址搜索) 爬(爬下数据) 取(去掉没用 ...

  4. python 最佳实践与资源汇总

    python 最佳实践 (部分) 一. 结构化工程 文件 功能 README.rst readme LICENSE 许可证 setup.py 打包和发布管理 requirements.txt 开发依赖 ...

  5. Web前端开发最佳实践系列文章汇总

    Web前端开发最佳实践(1):前端开发概述 Web前端开发最佳实践(2):前端代码重构 Web前端开发最佳实践(3):前端代码和资源的压缩与合并 Web前端开发最佳实践(4):在页面中添加必要的met ...

  6. Ubuntu14.04+Beanstalkd1.9最佳实践

    目录 [TOC] 1.基本概念 1.1.什么是Beanstalkd?   Beanstalkd 是一个轻量级消息中间件,它最大特点是将自己定位为基于管道 (tube) 和任务 (job) 的工作队列. ...

  7. 8、Dockerfile介绍和最佳实践

    一.Dockerfile 概念 1.Dockerfile是什么 Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资源.配置等文件外,还包含了一些为运行时准备的一些配置参数(如 ...

  8. dockerfile 最佳实践及示例

    Dockerfile 最佳实践已经出现在官方文档中,地址在 Best practices for writing Dockerfiles.如果再写一份最佳实践,倒有点关公门前耍大刀之意.因此本篇文章是 ...

  9. go项目dockerfile最佳实践

    1. 前言 2. 不需要cgo情况下的最佳实践 3. 依赖cgo情况下的最佳实践 1. 前言 这几天在构建golang编写的web项目中,关于dockerfile编写的一些总结 可能是单纯我比较菜(大 ...

随机推荐

  1. 【别人的老师VS你的老师 】同样是老师,差别怎么这么大呢!?

  2. mysql Workbench 执行删除命令

    SET SQL_SAFE_UPDATES = 0;delete from table1; SET SQL_SAFE_UPDATES = 1;

  3. FFT

    void FFT(complex a[],int n,int fl){ ,j=n/;i<n;i++){ if (i<j) {complex t=a[i];a[i]=a[j];a[j]=t; ...

  4. [webpack] webpack-dev-server介绍及配置

    webpack-dev-server是webpack官方提供的一个小型Express服务器.使用它可以为webpack打包生成的资源文件提供web服务.webpack-dev-server官方文档 w ...

  5. .dwg(sw)-exb

    尺寸风格:除了标准外合并,合并好后删除. 文本风格:除了标准外合并,合并好后删除.

  6. Mysql 命令大全

    1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root - ...

  7. 关于Wireshark "The NPF driver isn’t running……"解决办法

    启动Wireshark软件时出现了如下图所示的错误,就搜索了一下解决方法,特总结如下: 这个错误是因为没有开启NPF服务造成的.简要说一下NPF吧. NPF即网 络数据包过滤器(Netgroup Pa ...

  8. nginx中将POST数据写到日志里面的正确方式

    http://www.cnblogs.com/meteorx/p/3188647.html

  9. c#使用正则表达式抓取a标签的链接和innerhtml

    //读取网页html string text = File.ReadAllText(Environment.CurrentDirectory + "//test.txt", Enc ...

  10. 【CityHunter】通过Unity3D来制作游戏中AR部分的内容

    嗯,最近再考虑,CityHunter中,玩家攻略藏宝图时,为了增加可玩性,应该增强在AR部分的游戏性.最近特别火的游戏<Pokemon Go>在打开摄像头以后,可以看到小精灵,实际上,如果 ...