Golang Notes
我之前总结的Golang的一些notes,先暂时放在这里吧
- struct包含,比如Player包含了User,如果是匿名包含(即不给User域起名字)则可以直接使用定义在User上的方法,否则必须p.u.Method()
- 在一个struct内,对于每种类型,只能有一个匿名类型的field , 因为匿名类型可以作为该匿名的域名城
go
-
- reflect.Type 是一个接口对象,里面的方法包括Field,Name,String等
- reflect.Typeof( * ) refect.Type,返回某变量的reflect.Type
iota是0开始,自动增加,比如
const ( Sunday = iota // Sunday = 0 Monday // Monday = 1 ... Saturday // Saturday = 6 )
rune是处理utf-8,比如汉字,相关的内容what23,rune(“s”) 返回的是ascii码数值,如果是汉子,就是utf-8
import “log” 两种用法
第一种是输向标准错误,log.Println(), log.Fatal()
第二种是自建一个logger, logg = log.New(out io.Writer, 格式等); 然后logg.Println()
按域分割字符串
func strings.Fields(string) []string {}
array … 是拆开变量,类似于python中的 *list
函数传参
函数传参,是按values传参,自定义的struct,array等都是全copy;引用类型传参加&
引用类型,默认采用传引用的方法:slice、map、interface、channel
传递同类型未知个数参数使用
varname ...Type
,函数内部转化为[]int{},即slice传递不同类型的未知个数参数呢?使用空接口interface{}。尽量别这么用哈
func PrintType(variables ...interface{}) { for _, v := range variables { switch v.(type) { case int: fmt.Println("type is int %d", v) default: fmt.Println("other type %v", v) } } } func showFunctionMultiInterfaceParameters() { lemon.PrintType(5, "aaaa") var2 := []interface{}{6, 7, 9, "bbb", "ccc"} lemon.PrintType(var2...) }
package
不能对来自其他package中的struct定义方法
只有首字母大写的identifier(constant、variable、type、function、struct field,…)可以被import,起到了public的作用
把struct弄成小写,函数构造器弄成大写的,那么在包外,就只能使用构造器来申请资源了
pakcage matrix type matrix struct { ... } function NewMatrix(params) *matrix { m := new(matrix) //m is initialized return m }
package main import "matrix" wrong := new(matrix.matrix) //will not compile(matrix is private) right := matrix.NewMatrix(...) //the ONLY way to instantiate a matrix
Go 安装
官网下载go,配置GOROOT GOPATH
安装vim-go, 使用插件 vim-pathogen
mkdir -p ~/.vim/autoload ~/.vim/bundle curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim echo <<EOF >> ~/.vimrc execute pathogen#infect() syntax on filetype plugin indent on EOF cd ~/.vim/bundle/ && git clone https://github.com/fatih/vim-go.git
调试工具Delve:
- git clone https://github.com/go-delve/delve.git
- go get -v github.com/go-delve/delve/cmd/dlv
- git clone之后,其路径需要与go get的路径一致
vscode go
- 打开一个文件夹,创建一个.go文件,会自动提示你安装vscode go插件
- mkdir $GOPATH/src/golang.org/x && cd $GOPATH/src/golang.org/x
- git clone https://github.com/golang/tools.git tools
- go get -v github.com/sqs/goreturns
- Run Build Task 会提示你创建task.json,把command改成go run即可
- Start Debugging 应该是可以直接使用的
import “sync”
除了sync.Once和sync.WaitGroup类型外,其它类型大多用于low-level library routines,high-level的同步工作请使用channels和communication
import “container/heap”
heap.Init(h)
heap.Push(h, 3)
heap.Pop()
golang 反射的应用
http://licyhust.com/golang/2017/10/30/golang-reflect/ + 官网
两大类型Value和Type + interface{}桥梁 => 三大定律
- 反射可以将“接口类型变量”转换为“反射类型对象”
- 反射可以将“反射类型对象”转换为“接口类型变量”。
- 如果要修改“反射类型对象”,其值必须是“可写的”(settable)
用于操作任意类型对象
- 修改结构体信息
获取结构信息
func reflect.TypeOf(i interface{}) reflect.Type # 返回的是一个接口,该接口代表了i的动态类型 func reflect.ValueOf(i interface{}) reflect.Value # 返回的是一个结构体,代表了i的动态值
reflect包中有以Type和Value作参数的函数,最重要的是就是上面的TypeOf和ValueOf
reflect.Type 接口内有很多方法,接口对应的动态类型必须实现了这些方法
reflect.Value上也定义了一些方法
To Read => Summary
工业级go编程 Go for Industrial Programming
https://www.weave.works/blog/kubernetes-horizontal-pod-autoscaler-and-prometheus
https://www.weave.works/blog/kubernetes-best-practices
- 完成同一个功能的不同版本,让它们有共同的父package
- app = domain types + Services
- domain type 描述类型和行为,是app的实体。每个单独的package。struct表示类型+interface表示操作
- Services :domain接口的实现,由dependency管理(外部数据+传输逻辑),每个dependency一个package。
- 举例:struct Product,对应产品存储方法 interface ProductService,依赖外部存储比如nfs
- 命名
- 标量用重复字符代表集合/数组等,var tt []*Thing
- 同一个Domain Type下有多个类型,那么一个Package,每个类型一个文件
- 尽量避免else
- 某package内的变量命就不要包含包信息了,比如log.LogInfo -> log.Info()
- 介绍一个go项目所需要的工具、配置、编译等等。
- 介绍了go interfaces和method的内部实现方式,通过汇编展示
we_are_kubernetes_developers_ask_us_anything/
- 问了啥?回答了啥?
https://blog.chewxy.com/2018/03/18/golang-interfaces/
- Accept interfaces, return structs
https://kubernetes.io/blog/2018/03/principles-of-container-app-design/
https://www.weave.works/blog/kops-vs-kubeadm
https://github.com/enocom/gopher-reading-list
- 介绍了很多优化技巧,可以看一看