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 := [...]int{0,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. 单元测试和压力测试

原文地址:https://www.cnblogs.com/share-ideas/p/11219129.html

时间: 2024-10-20 14:18:29

golang编程实践总结的相关文章

Golang 高效实践之并发实践

前言 在我前面一篇文章Golang受欢迎的原因中已经提到,Golang是在语言层面(runtime)就支持了并发模型.那么作为编程人员,我们在实践Golang的并发编程时,又有什么需要注意的点呢?下面我会跟大家详细的介绍一些在实际生产编程中很容易踩坑的知识点. CSP 在介绍Golang的并发实践前,有必要先介绍简单介绍一下CSP理论.CSP,全称是Communicating sequential processes,翻译为通信顺序进程,又翻译为交换消息的顺序程序,用来描述并发性系统的交互模式.

Linux shell一行流编程实践

Linux下很多命令用起来真相当方便,尤其是进行批处理操作时.(话说感觉这种程序也不复杂,windows咋一直不搞一个好用的shell呢) 这里列出一些常用shell操作的应用,具体命令的用法与解释就不列了,网上有很多很好的教程. 批量重命名 假如当前目录下有若干.wma文件,我希望把它们批量转成.mp3文件 例: 001.wma -> 001.mp3 解决方案: awk ? 1 ls * | awk -F '.' '{print "mv "$0" "$1&q

Socket编程实践(10) --select的限制与poll的使用

select的限制 用select实现的并发服务器,能达到的并发数一般受两方面限制: 1)一个进程能打开的最大文件描述符限制.这可以通过调整内核参数.可以通过ulimit -n(number)来调整或者使用setrlimit函数设置,但一个系统所能打开的最大数也是有限的,跟内存大小有关,可以通过cat /proc/sys/fs/file-max 查看 /**示例: getrlimit/setrlimit获取/设置进程打开文件数目**/ int main() { struct rlimit rl;

试读《JavaScript语言精髓与编程实践》

有幸看到iteye的活动,有幸读到<JavaScript语言精髓与编程实践_第2版>的试读版本,希望更有幸能完整的读到此书. 说来读这本书的冲动,来得很诡异,写一篇读后感,赢一本书,其实奖励并不大,依靠纯粹的物质奖励,很显然,不会强烈的促使我去读这本书.而原因在于,一方面对javascript的极大兴趣,另一方面之前已经拜读过如<javascript高级程序设计><高性能javascript><javascript设计模式>等书,那我就有了要看看这本书都写了

并发编程实践五:ReentrantLock

ReentrantLock是一个可重入的互斥锁,实现了接口Lock,和synchronized相比,它们提供了相同的功能,但ReentrantLock使用更灵活,功能更强大,也更复杂.这篇文章将为你介绍ReentrantLock,以及它的实现机制. ReentrantLock介绍 通常,ReentrantLock按下面的方式使用: public class ReentrantLockTest { private final ReentrantLock lock = new ReentrantLo

郑捷《机器学习算法原理与编程实践》学习笔记(第六章 神经网络初步)6.3 自组织特征映射神经网路(SMO)

具体原理网址:http://wenku.baidu.com/link?url=zSDn1fRKXlfafc_tbofxw1mTaY0LgtH4GWHqs5rl8w2l5I4GF35PmiO43Cnz3YeFrrkGsXgnFmqoKGGaCrylnBgx4cZC3vymiRYvC4d3DF3 自组织特征映射神经网络(Self-Organizing Feature Map.也称Kohonen映射),简称为SMO网络,主要用于解决模式识别类的问题.SMO网络属于无监督学习算法,与之前的Kmeans算

《机器学习算法原理与编程实践》学习笔记(二)

(上接第一章) 1.2 对象.矩阵与矢量化编程 1.2.1对象与维度(略) 1.2.2初识矩阵(略) 1.2.3矢量化编程与GPU运算(略) 1.2.4理解数学公式与NumPy矩阵运算 1.矩阵的初始化 #coding:utf-8 import numpy as np #导入NumPy包 #创建3*5的全0矩阵和全1的矩阵 myZero = np.zeros([3,5])#3*5的全0矩阵 print myZero myZero = np.ones([3,5])##3*5的全1矩阵 print

Socket编程实践(6) --TCP粘包原因与解决

流协议与粘包 粘包的表现 Host A 发送数据给 Host B; 而Host B 接收数据的方式不确定 粘包产生的原因 说明 TCP 字节流,无边界 对等方,一次读操作,不能保证完全把消息读完 UDP 数据报,有边界 对方接受数据包的个数是不确定的 产生粘包问题的原因分析 1.SQ_SNDBUF 套接字本身有缓冲区 (发送缓冲区.接受缓冲区) 2.tcp传送的端 mss大小限制 3.链路层也有MTU大小限制,如果数据包大于>MTU要在IP层进行分片,导致消息分割. 4.tcp的流量控制和拥塞控

《机器学习算法原理与编程实践》学习笔记(三)

(上接第一章) 1.2.5 Linalg线性代数库 在矩阵的基本运算基础之上,NumPy的Linalg库可以满足大多数的线性代数运算. .矩阵的行列式 .矩阵的逆 .矩阵的对称 .矩阵的秩 .可逆矩阵求解线性方程 1.矩阵的行列式 In [4]: from numpy import * In [5]: #n阶矩阵的行列式运算 In [6]: A = mat([[1,2,3],[4,5,6],[7,8,9]]) In [7]: print "det(A):",linalg.det(A)