golang编程实践总结

Posted share-ideas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang编程实践总结相关的知识,希望对你有一定的参考价值。

一、语法基础

  1. main函数在main包,每个代码文件中的init函数都将在main函数执行前调用。
  2. 同一文件夹中代码使用同一包名,且一般包与文件夹名一致。
  3. 同一包中的变量和类型、标识符可直接使用,包名类型命名空间,包中每个文件对应一个独立的职责。
  4. 将包导入其他文件中,可通过包名间接访问首字母大写的标识符,所定义的对象也只能访问首字母开头的成员变量或函数。
  5. 所有变量被初始化的零值:数值(0),字符串(""),布尔(false),指针(nil),引用类型(返回nil作为其值,但引用的底层数据结构会初始化为对应的零值)。
  6. Go中的引用类型有:map, slice, channel, func。
  7. 广泛使用指针或引用类型来传递变量,但其指针不支持指针运算。
  8. 函数定义(属于包)和方法定义(属于结构体)的区别
  9. 垃圾回收器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编程实践总结的主要内容,如果未能解决你的问题,请参考以下文章

Golang 高效实践之并发实践

编程实践Golang 生成PDF

编程实践Golang 实现 Yaml编码和解码

编程实践Golang 获取HTTP请求的IP地址

编程实践Golang 实现中文分词

编程实践Golang 字符串数组排序