golang编程实践总结
Posted share-ideas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang编程实践总结相关的知识,希望对你有一定的参考价值。
一、语法基础
- main函数在main包,每个代码文件中的init函数都将在main函数执行前调用。
- 同一文件夹中代码使用同一包名,且一般包与文件夹名一致。
- 同一包中的变量和类型、标识符可直接使用,包名类型命名空间,包中每个文件对应一个独立的职责。
- 将包导入其他文件中,可通过包名间接访问首字母大写的标识符,所定义的对象也只能访问首字母开头的成员变量或函数。
- 所有变量被初始化的零值:数值(0),字符串(""),布尔(false),指针(nil),引用类型(返回nil作为其值,但引用的底层数据结构会初始化为对应的零值)。
- Go中的引用类型有:map, slice, channel, func。
- 广泛使用指针或引用类型来传递变量,但其指针不支持指针运算。
- 函数定义(属于包)和方法定义(属于结构体)的区别
- 垃圾回收器GC:
二、常用数据结构及使用方法
1. map: map[key]value
//key类型须支持==和!=运算符,不能为浮点数 var matchers = make(map[string]string) ages := make(map[string]int),ages := make(map[string]int) //空map //slice语法创建 ages := map[string]int "alice": 31, "charlie": 34, 访问元素:ages["alice"] = 33 if age, ok := ages["bob"]; !ok /* ... */ //map中的元素不是变量,不能寻址 //遍历(遍历顺序不定) // 迭代切片里的元素 for name, age := range ages fmt.Printf("%s\t%d\n", name, age)
2. 数组:固定长度,较少使用
var arrInt [8]int td := [...]int0,4,5,2 //数组引用(将数组引用或指针传入函数) func toZero(p *[32]byte) for i := range p p[i] = 0 func toZero1(p *[32]byte) *p = [32]byte
3. slice: 底层使用数组实现,但长度可扩展,传递切片即引用同一对象
var names []string for name := range ages names = append(names, name) s := arr[:] //初始化切片为数组arr的引用 //提前给slice分配一个合适的大小,避免内存分配和拷贝 names := make([]string, 0, len(ages)) //创建一个空的slice,容量为len //在函数间传递切片
4. struct: 结构体或类型
type books struct title string author string subject string id int book := &books title: "Go Lang", author: "peter" book := books"Go", "Peter"
5. channel:
cStop := make(chan bool, 1) // Create an unbuffered channel. baton := make(chan int)
6. interface: 接口,可用于实现多态特性,只要某个结构体实现了接口类中的所有方法即可作为该接口的子类
type public interface Topic() string Message() *Message Ack() error type publication struct d amqp.Delivery m *Message t string func (p *publication) Ack() error return p.d.Ack(false) func (p *publication) Topic() string return p.t func (p *publication) Message() *Message return p.m func (p publication) Message() *Message return p.m
type PubSub struct host string type mock struct //其中mock和PubSub都实现了Publish和Subscribe两个接口 pubs := []publisher pubsub.New("localhost"), &mock, for _, p := range pubs p.Publish("key", "value") p.Subscribe("key")
8. func: 函数或方法
func add(x, y int) int return x + y func swap(x, y string) (string, string) return y, x func add(x, y int) (z int) z = x + y return func sum(numbers ...int) int s := 0 for i := range numbers s += i return s //匿名函数,闭包 var v func(a int) int v = func(a int) int return a * a fmt.Println(v(6)) //两种写法 v1 := func(i int) int return i * i fmt.Println(v1(7))
9. 继承与组合
/* 继承 一个结构体嵌到另一个结构体,称作组合 匿名和组合的区别 如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现继承 如果一个struct嵌套了另一个【有名】的结构体,那么这个模式叫做组合 如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的方法,从而实现多重继承 */ type Car struct weight int name string func (p *Car) Run() fmt.Println("running") type Bike struct Car cycles int package main import ( "fmt" ) type People struct type People2 struct func (p *People) ShowA() fmt.Println("showA") p.ShowB() func (p *People) ShowB() fmt.Println("showB") func (p *People) ShowC() fmt.Println("showC") func (p *People) ShowD() fmt.Println("People:showD") func (p *People2) ShowD() fmt.Println("People2:showD") type Teacher struct People //组合People People2 //组合People2 func (t *Teacher) ShowB() fmt.Println("teacher showB") func (t *Teacher) ShowC(arg string) fmt.Println(arg) func main() t := Teacher //print showA //print showB t.ShowA() //print teacher showB t.ShowB() //print showB t.People.ShowB() //print test t.ShowC("test") //print showC t.People.ShowC() //因为组合方法中多次包含ShowD,所以调用时必须显示指定匿名方法 //print People2:showD t.People2.ShowD()
10. 并发数据结构
//同步等待: var wg sync.WaitGroup wg.Add(2) defer wg.Done() wg.Wait() runtime.Gosched() //原子操作: atomic.AddInt64(&counter, 1) time.Sleep(1 * time.Second) atomic.StoreInt64(&shutdown, 1) atomic.LoadInt64(&shutdown) //加锁: mutex.Lock() mutex.Unlock() //随机数: rand.Seed(time.Now().UnixNano()) n := rand.Intn(100)
三、常用编程模式或框架
1. 并发模式
/* 1.runner包,调度后台处理任务,监视程序执行时间 【for-select结构】 通过执行返回可判断是超时、系统中断还是正常完成任务 2.pool包,有缓冲的通道实现资源池,管理多个协程间共享及独立使用的资源。[一组静态资源,数据库连接或内存缓冲区] 取得资源,归还资源,归还资源时应加互斥锁 3.work包,无缓冲通过,保证数据能及时处理,实时交换数据。生产者与消费者模型 */
2. 编解码
3. 单元测试和压力测试
以上是关于golang编程实践总结的主要内容,如果未能解决你的问题,请参考以下文章