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.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.2.1 通过带有接受者函数实现,使用起来函数作为了对象的属性
1.4.2.2 golang可以自动匹配接受者的类型,不管是对象还是对象的指针
1.4.2.3 字段继承通过匿名字段实现;方法继承/重写也通过匿名字段实现
1.4.3.1 接口定义协议,通过带接受者的函数实现接口,实现了接口的对象可以被接口引用
1.4.3.2 面向接口不是对面向对象的否定,它是面向对象编程体系中的思想精髓之一
1.4.3.3 面向接口编程的本质是面向协议编程,只要实现了该协议,不管什么对象都是可以随时替代的,可以提高软件的灵活性与可维护性opic
1.4.3.4 面向对象是为了实现代码复用,面向接口是为了实现多态、实现标准定制、灵活替代
2.1 使用交叉编译工具或者使用Golang指定目标编译
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.1.1 error也是值,并且需要总是检查error并对其处理
3.2.2 模仿Web开发模式,子模块只管抛出异常,并在全局位置捕获异常统一处理,即使用panic、recover、defer等联合进行处理
3.2.3 defer参数值是在声明时确定,而不是在调用时才确定
4.1.1 全局变量使用var声明,内部变量尽量使用简短方式声明/定义,需要明确指定变量类型的除外
4.1.2 常量可以指定为数值、布尔值或字符串等类型,格式:const constantName = value
4.1.3 同时声明多个常量、变量,或者导入多个包时,可采用分组的方式进行声明,适用于import/const/var
4.2.1 整型、浮点型、复数默认类型分别为int/float64/complex128
4.2.2.1 bool-false, string-"", 整型、浮点型、复数-0
4.2.2.3 array需要指定长度,讨论其默认值没有意义
4.2.2.4 初始声明未初始化的slice/map默认为nil
4.2.3.1 声明初始化、make/new初始化、赋值初始化
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.1 字符串连接使用+运算符或者使用fmt格式化返回字符串
4.3.2.2 字符串为不可变类型,如果需要改变字符串值,需要转化为[]byte/[]rune切片进行操作
4.3.2.3 字符串使用UTF-8编码存储,如果需要按照Unicode方式进行操作,需要转化为[]rune切片或者使用"unicode/utf8"包
4.3.3.1 定义数组必须指定长度,且数组长度定义之后不能改变
4.3.3.2 数组赋值为值的赋值,参数传递也是值传递,即实参数组赋值一份数据给形参数组
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.1 map、channel、slice为引用类型 如果两个引用类型同时指向一个底层,那么一个改变,另一个也相应的改变 三者都可以通过for...range遍历
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.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.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.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.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.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.1 当所有发送操作结束时,每个阶段都关闭自己的 outbound channels
4.4.5.4.2.6.2 每个阶段都会一直从 inbound channels 接收数据,直到这些 channels 被关闭,或发送者解除阻塞状态
4.5.1.1 支持多返回值与变参,总是命名返回值,可以直接return
4.5.1.2 值类型(array/struct)为传值调用--参数赋值,引用类型(channel/map/slice,指针等)为传递地址调用--参数引用
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.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.1 golang的反射与Java相比功能弱很多,golang不支持解析string然后执行
4.5.2.5.2 golang的反射机制只能存在于已经存在的对象/类型上面
4.5.2.5.3 如果要实现与Java一样的反射(RPC/Web框架)机制, 需要先把字符串和类的reflect.Typeof关联好,然后根据字符串找到对应的类型,用reflect.New构造对象就可以了 即需要提前有注册机制进行字符串<-->类型的关联映射
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 语言实现一样
- Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践
目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ? RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...
- Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目
Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...
- Golang - 爬虫案例实践
目录 Golang - 爬虫案例实践 1. 爬虫步骤 2. 正则表达式 3. 并发爬取美图 Golang - 爬虫案例实践 1. 爬虫步骤 明确目标(确定在哪个网址搜索) 爬(爬下数据) 取(去掉没用 ...
- python 最佳实践与资源汇总
python 最佳实践 (部分) 一. 结构化工程 文件 功能 README.rst readme LICENSE 许可证 setup.py 打包和发布管理 requirements.txt 开发依赖 ...
- Web前端开发最佳实践系列文章汇总
Web前端开发最佳实践(1):前端开发概述 Web前端开发最佳实践(2):前端代码重构 Web前端开发最佳实践(3):前端代码和资源的压缩与合并 Web前端开发最佳实践(4):在页面中添加必要的met ...
- Ubuntu14.04+Beanstalkd1.9最佳实践
目录 [TOC] 1.基本概念 1.1.什么是Beanstalkd? Beanstalkd 是一个轻量级消息中间件,它最大特点是将自己定位为基于管道 (tube) 和任务 (job) 的工作队列. ...
- 8、Dockerfile介绍和最佳实践
一.Dockerfile 概念 1.Dockerfile是什么 Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资源.配置等文件外,还包含了一些为运行时准备的一些配置参数(如 ...
- dockerfile 最佳实践及示例
Dockerfile 最佳实践已经出现在官方文档中,地址在 Best practices for writing Dockerfiles.如果再写一份最佳实践,倒有点关公门前耍大刀之意.因此本篇文章是 ...
- go项目dockerfile最佳实践
1. 前言 2. 不需要cgo情况下的最佳实践 3. 依赖cgo情况下的最佳实践 1. 前言 这几天在构建golang编写的web项目中,关于dockerfile编写的一些总结 可能是单纯我比较菜(大 ...
随机推荐
- 【别人的老师VS你的老师 】同样是老师,差别怎么这么大呢!?
- mysql Workbench 执行删除命令
SET SQL_SAFE_UPDATES = 0;delete from table1; SET SQL_SAFE_UPDATES = 1;
- 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; ...
- [webpack] webpack-dev-server介绍及配置
webpack-dev-server是webpack官方提供的一个小型Express服务器.使用它可以为webpack打包生成的资源文件提供web服务.webpack-dev-server官方文档 w ...
- .dwg(sw)-exb
尺寸风格:除了标准外合并,合并好后删除. 文本风格:除了标准外合并,合并好后删除.
- Mysql 命令大全
1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root - ...
- 关于Wireshark "The NPF driver isn’t running……"解决办法
启动Wireshark软件时出现了如下图所示的错误,就搜索了一下解决方法,特总结如下: 这个错误是因为没有开启NPF服务造成的.简要说一下NPF吧. NPF即网 络数据包过滤器(Netgroup Pa ...
- nginx中将POST数据写到日志里面的正确方式
http://www.cnblogs.com/meteorx/p/3188647.html
- c#使用正则表达式抓取a标签的链接和innerhtml
//读取网页html string text = File.ReadAllText(Environment.CurrentDirectory + "//test.txt", Enc ...
- 【CityHunter】通过Unity3D来制作游戏中AR部分的内容
嗯,最近再考虑,CityHunter中,玩家攻略藏宝图时,为了增加可玩性,应该增强在AR部分的游戏性.最近特别火的游戏<Pokemon Go>在打开摄像头以后,可以看到小精灵,实际上,如果 ...