golang

golang中defer和recover的使用

不羁的心 提交于 2019-12-05 00:15:04
defer 内建函数,所在方法里退出时调用,一个方法里若有多个defer语句,则先声明的后被调用,一般与recover()函数一起配合使用,recover()一般用于捕捉panic抛出的异常,比如:panic(11), 捕捉到的就是11 func main() { defer func() { if v := recover();v == 11 { fmt.Printf("v: %#v\n",v) } fmt.Printf("defer1...\n") }() defer func() { fmt.Printf("defer2...\n") }() array := [2]int{1,2} fmt.Println("array: ",array[1]) panic(11) /*输出: array: 2 defer2... v: 11 defer1... */ } 来源: CSDN 作者: 晓恩ghm 链接: https://blog.csdn.net/qq_29291085/article/details/84883878

Golang教程第32节--panic 和 recover

半城伤御伤魂 提交于 2019-12-05 00:12:56
原文来自: https://golangbot.com/panic-and-recover/ 什么是 panic? 在 Go 语言中,程序中一般是使用错误来处理异常情况。对于程序中出现的大部分异常情况,错误就已经够用了。 但在有些情况,当程序发生异常时,无法继续运行。在这种情况下,我们会使用 panic 来终止程序。当函数发生 panic 时,它会终止运行,在执行完所有的defer函数后,程序控制返回到该函数的调用方。这样的过程会一直持续下去,直到当前协程的所有函数都返回退出,然后程序会打印出 panic 信息,接着打印出堆栈跟踪(Stack Trace),最后程序终止。在编写一个示例程序后,我们就能很好地理解这个概念了。 在本教程里,我们还会接着讨论,当程序发生 panic 时,使用 recover 可以重新获得对该程序的控制。 可以认为 panic 和 recover 与其他语言中的 try-catch-finally 语句类似,只不过一般我们很少使用 panic 和 recover 。而当我们使用了 panic 和 recover 时,也会比 try-catch-finally 更加优雅,代码更加整洁。 什么时候应该使用 panic? 需要注意的是,你应该尽可能地使用错误,而不是使用 panic 和 recover。只有当程序不能继续运行的时候,才应该使用 panic 和

Golang学习 - sync 包

☆樱花仙子☆ 提交于 2019-12-05 00:11:48
Golang学习 - sync 包 ------------------------------------------------------------ 临时对象池   Pool 用于存储临时对象,它将使用完毕的对象存入对象池中,在需要的时候取出来重复使用,目的是为了避免重复创建相同的对象造成 GC 负担过重。其中存放的临时对象随时可能被 GC 回收掉(如果该对象不再被其它变量引用)。   从 Pool 中取出对象时,如果 Pool 中没有对象,将返回 nil ,但是如果给 Pool.New 字段指定了一个函数的话,Pool 将使用该函数创建一个新对象返回。   Pool 可以安全的在多个例程中并行使用,但 Pool 并不适用于所有空闲对象,Pool 应该用来管理并发的例程共享的临时对象,而不应该管理短寿命对象中的临时对象,因为这种情况下内存不能很好的分配,这些短寿命对象应该自己实现空闲列表。   Pool 在开始使用之后,不能再被复制。 ------------------------------ type Pool struct { // 创建临时对象的函数 New func () interface {} } // 向临时对象池中存入对象 func (p *Pool) Put (x interface {}) // 从临时对象池中取出对象 func (p *Pool)

golang 1.8 并发安全Map简单实现

我怕爱的太早我们不能终老 提交于 2019-12-05 00:11:21
type SafeMap struct { sync.RWMutex Map map [ int64 ] string } func NewSafeMap(size int ) *SafeMap { sm := new (SafeMap) sm.Map = make ( map [ int64 ] string , size) return sm } func (sm *SafeMap) ReadMap(key int64 ) string { sm.RLock() value := sm.Map[key] sm.RUnlock() return value } func (sm *SafeMap) WriteMap(key int64 , value string ) { sm.Lock() sm.Map[key] = value sm.Unlock() } // 用于for k,_ := range m.Keys(){v := m.ReadMap(k) ....} func (sm *SafeMap) Keys() [] int64 { sm.RLock() value := make ([] int64 , 0 ) for k, _ := range sm.Map { value = append (value, k) } sm.RUnlock() return value

golang中map声明及初始化

南笙酒味 提交于 2019-12-05 00:09:58
map的声明 var m1 map[string]int map[key]value key必须支持==(避免使用浮点型)value不做规范 map的初始化 方式1 var m1 map[string]int=map[sting]int{"key":0} 方式2 m2:=make(map[string]int) 注意: map声明后初始化前,可进行查找、删除、len和range操作,并不会报错 map声明后不能进行赋值,只有初始化后才能进行赋值操作 来源: CSDN 作者: lnsx0001 链接: https://blog.csdn.net/lnsx0001/article/details/53443293

golang并发--syn/atomic包

…衆ロ難τιáo~ 提交于 2019-12-05 00:09:30
sync/atomic包提供了原子操作,即进行过程中不能被中断的操作。 该包提供的可进行原子操作类型包括int32,int64,uint32,uint64,uintptr,unsafe.Pointer,共六个。 这些函数提供的原子操作共有五种:增减,比较并交换,载入,存储和交换。 增减 Add 函数名称都以Add为前缀,并后跟针对的具体类型的名称: func AddInt32(addr *int32, delta int32) (new int32) AddInt64(addr *int64, delta int64) (new int64) func AddUint32(addr *uint32, delta uint32) (new uint32) func AddUint64(addr *uint64, delta uint64) (new uint64) func AddUintptr(addr *uintptr, delta uintptr) (new uintptr) 被操作的类型只能是数值类型,int32,int64,uint32,uint64,uintptr类型可以使用原子增或减操作。 第一个参数值必须是一个指针类型的值,以便施加特殊的CPU指令。 第二个参数值的类型和第一个被操作值的类型总是相同的。 示例: package main import ( "sync

golang学习第一篇 golang简介

主宰稳场 提交于 2019-12-05 00:09:11
golang简介 很久没写博客了,最近在学golang。为了总结学习经验,博客又派上用场了。 golang 是由谷歌的三位大牛发明并开源出来的,具体哪三位请大家自行搜索。 博主使用过这些计算机语言:C/C++、VB、C#、PHP、javascript、python、erlang。目前使用erlang从事即时通讯后台开发,期间也接触一些golang的开源项目。虽然很早就了解过golang,但没系统的学习过。 对比之前用过的计算机语言,golang有这些优点: 1、简单 golang里的变量可以不用定义而直接使用,golang会自行推导出变量的类型以及是否定义过。 例如: type Student struct{ name string age int } student := Student{ "Bob", 12} 在上面的代码中,:= 运算符会要求golang检查变量 student 是否被定义过。如果没有被定义,golang会自动定义,并赋值;如果该变量已经定义,那么golang会报错提示该变量已经被定义过。 从上面代码中我们还可以看到几个其他的优点:行尾不需要结束符(如C/C++的“;”, erlang的 “,” 等);定义变量(或新类型)时类型在变量(或新类型)名称的后面,这样做的好处是让开发者更加关心变量(或新类型)本身,而无需太关心其类型

golang中sync.RWMutex和sync.Mutex

依然范特西╮ 提交于 2019-12-05 00:02:50
golang中sync.RWMutex和sync.Mutex区别 转自:http://blog.csdn.net/chenbaoke/article/details/41957725 golang中sync包实现了两种锁Mutex (互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能. type Mutex func (m *Mutex) Lock() func (m *Mutex) Unlock() type RWMutex func (rw *RWMutex) Lock() func (rw *RWMutex) RLock() func (rw *RWMutex) RLocker() Locker func (rw *RWMutex) RUnlock() func (rw *RWMutex) Unlock() 其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁. func (m *Mutex) Unlock()用于解锁m, 如果在使用Unlock()前未加锁,就会引起一个运行错误.

GOLANG sync.Mutex和sync.RWMutex

自古美人都是妖i 提交于 2019-12-05 00:02:29
完整教程,请参考如下链接: 点击打开链接 Package sync type Mutex A Mutex is a mutual exclusion lock. Mutexes can be created as part of other structures; the zero value for a Mutex is an unlocked mutex. A Mutex must not be copied after first use. type Mutex struct { // contains filtered or unexported fields } Mutex是最简单的一种锁类型,同时也比较粗暴,当一个goroutine获得了Mutex后,其他goroutine只能乖乖等待这个goroutine释放该Mutex. func (*Mutex) Lock func (m * Mutex ) Lock() Lock locks m. If the lock is already in use, the calling goroutine blocks until the mutex is available. func (*Mutex) Unlock func (m * Mutex ) Unlock() Unlock unlocks m. It is a run

golang mutex使用及注意事项

谁说胖子不能爱 提交于 2019-12-05 00:01:58
golang mutex使用及注意事项 关于使用 metux的出现是为了防止资源竞争(race conditions) 调用Lock()获得锁,调用unlock()释放锁。 mutex是互斥锁。若一个goroutine获得锁,则其他goroutine会一直阻塞到他释放锁后才能获得锁。 注意事项 多次调用Lock()函数 使用Lock()加锁后,不能再继续对其加锁(同一个goroutine中,即:同步调用),否则会panic。只有在unlock()之后才能再次Lock()。异步调用Lock(),是正当的锁竞争。当然不会有panic了 如下: package mutex import ( "sync" "fmt" ) var sum = 0 var mutex sync .M utex func A () { mutex .L ock () fmt .P rintln ( "get the lock" ) B () mutex .U nlock () } func B () { mutex .L ock () fmt .P rintln ( "Hello, World" ) mutex .U nlock () } package mutex import "testing" func TestA(t *testing.T) { A() } /** 输出: get the lock