Golang的一些学习
在 Go 中使用命名返回变量捕获 panic
在下面代码中,如果pressButton发生panic,那么不会执行到return err,导致返回的err是nil。
func doStuff() error {
var err error
// If there is a panic we need to recover in a deferred func
defer func() {
if r := recover(); r != nil {
err = errors.New("the meeseeks went crazy!")
}
}()
pressButton()
return err
}
可以使用命名返回变量解决,即使我们从未触碰到 doStuff 函数的末尾的返回语句,也会立刻返回这个 err 变量。
func doStuff() (err error) {
// If there is a panic we need to recover in a deferred func
defer func() {
if r := recover(); r != nil {
err = errors.New("the meeseeks went crazy!")
}
}()
pressButton()
return err
}
重新切片(slice)
从 slice 中重新切出新 slice 时,新 slice 会引用原 slice 的底层数组,将导致难以预料的内存使用。可以通过拷贝临时 slice 的数据,而不是重新切片来解决:
func get() (res []byte) {
raw := make([]byte, 10000)
fmt.Println(len(raw), cap(raw), &raw[0]) // 10000 10000 0xc420080000
res = make([]byte, 3)
copy(res, raw[:3])
return
}
func test() {
slice := a[2:3:4]
//可以利用第三个参数控制容量
//如果设置容量和长度相同,可以append时新创建底层数组,不影响原有的
}
类型声明与方法
从一个现有的非 interface 类型创建新类型时,并不会继承原有的方法:
// 定义 Mutex 的自定义类型
type myMutex sync.Mutex
func main() {
var mtx myMutex
mtx.Lock()
mtx.UnLock()
}
//mtx.Lock undefined (type myMutex has no field or method Lock)…
如果你需要使用原类型的方法,可将原类型以匿名字段的形式嵌到你定义的新 struct 中:
// 类型以字段形式直接嵌入
type myLocker struct {
sync.Mutex
}
func main() {
var locker myLocker
locker.Lock()
locker.Unlock()
}
for + 闭包函数
type field struct {
name string
}
func (p *field) print() {
fmt.Println(p.name)
}
// 错误示例
func main() {
data := []field{{"one"}, {"two"}, {"three"}}
for _, v := range data {
go v.print()
}
time.Sleep(3 * time.Second)
// 输出 three three three
}
// 正确示例
func main() {
data := []field{{"one"}, {"two"}, {"three"}}
for _, v := range data {
v := v
go v.print()
}
time.Sleep(3 * time.Second)
// 输出 one two three
}
// 正确示例
func main() {
data := []*field{{"one"}, {"two"}, {"three"}}
for _, v := range data { // 此时迭代值 v 是三个元素值的地址,每次 v 指向的值不同
go v.print()
}
time.Sleep(3 * time.Second)
// 输出 one two three
}
defer函数参数
对 defer 延迟执行的函数,它的参数会在声明时候就会求出具体值,而不是在执行时才求值:
// 在 defer 函数中参数会提前求值
func main() {
var i = 1
defer fmt.Println("result: ", func() int { return i * 2 }())
i++
}
select default
如果有default子句,case不满足条件时执行该语句。
如果没有default字句,select将阻塞,直到某个case可以运行;Go不会重新对channel或值进行求值。
缓冲通道中,刚好相反,由于元素值的传递是异步的,所以发送操作在成功向通道发送元素值之后就会立即结束(它不会关心是否有接收操作)。
如果使用非缓冲,ret值必须被接收。如果此函数等待超时直接返回nil,会导致Ret这个Chan在模块那边写不进去堵死。
func (m *friendModule) Gift*****(cmd GiftCmd) *GiftRet {
ctx, cancel := context.WithTimeout(context.Background(), util.ASyncCmdTimeOut)
defer cancel()
cmd.Ret = make(chan GiftRet, 1) ##非缓冲bug
select {
case m.GiftChan <- cmd:
case <-ctx.Done():
logs.Error("friend moduel gift cmdChan is full")
}
select {
case ret := <-cmd.Ret:
return &ret
case <-ctx.Done():
logs.Error("friend moduel gift cmdChan apply <-retChan timeout")
return nil
}
}
Golang的一些学习的更多相关文章
- Golang源码学习:调度逻辑(二)main goroutine的创建
接上一篇继续分析一下runtime.newproc方法. 函数签名 newproc函数的签名为 newproc(siz int32, fn *funcval) siz是传入的参数大小(不是个数):fn ...
- Golang之sdl2学习之路(零) -- 环境工具准备
学习Golang有一段时间了,从毫无头绪到四处乱撞,再到如今静下心来安心学习sdl2也有小半年了. 今晚重构之前的学习代码,发现如果不写该文,可能会在以后回顾这段时间写的代码上花费时间,故以此文做一点 ...
- golang 容器的学习与实践
golang 提供了几个简单的容器供我们使用,本文在介绍几种Golang 容器的基础上,实现一个基于Golang 容器的LRU算法. 容器介绍 Golang 容器位于 container 包下,提供了 ...
- [Golang] Gin框架学习笔记
0x0 Gin简介 1.Gin 是什么? Gin 是一个用 Go (Golang) 编写的 HTTP web 框架. 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httpr ...
- golang net包学习笔记
阅读源代码发现在net包中主要实现了ip.tcp.udp.unix等通信方式.它们大致可以分成两大类:其一,ip.udp.unix(DGRAM),这是一些无链接的协议,其二,tcp.unix(STRE ...
- golang 要去学习的文档记录
xrom开发文档地址: http://gobook.io/read/github.com/go-xorm/manual-zh-CN/chapter-10/ golang基础知识: https://ww ...
- Golang gin框架学习
今天开始学习gin框架,在Github上找的示例的go-gin-example, 进度 日期 进展 疑惑 进展 1.30 下拉代码,初步了解gin的介绍.搭建 .mod文件 module原理.使用方法 ...
- Golang源码学习:使用gdb调试探究Golang函数调用栈结构
本文所使用的golang为1.14,gdb为8.1. 一直以来对于函数调用都仅限于函数调用栈这个概念上,但对于其中的详细结构却了解不多.所以用gdb调试一个简单的例子,一探究竟. 函数调用栈的结构(以 ...
- Golang源码学习:调度逻辑(一)初始化
本文所使用的Golang为1.14,dlv为1.4.0. 源代码 package main import "fmt" func main() { fmt.Println(" ...
- Golang源码学习:调度逻辑(四)系统调用
Linux系统调用 概念:系统调用为用户态进程提供了硬件的抽象接口.并且是用户空间访问内核的唯一手段,除异常和陷入外,它们是内核唯一的合法入口.保证系统的安全和稳定. 调用号:在Linux中,每个系统 ...
随机推荐
- cmake ccmake
下载libqrencode源码编译过程 git clone https://github.com/fukuchi/libqrencode.git 2001 mkdir build 2002 cd ...
- Loj #2036. 「SHOI2015」自动刷题机
link : https://loj.ac/problem/2036 这个显然具有单调性,N小的话更容易A题,不仅因为A一次题减少的代码,并且A题的下限也低. 所以直接上二分就行了,注意上限一定不要设 ...
- Nessus虚拟机的几个问题解决办法
1.使用ppp的校园网或者家庭宽带无法通过桥接上网. 这时要把这俩网卡变成NAT模式就行. 2.国外下载插件包(或者过慢). 我这里贡献个高速链接.base64,懂得自然懂. c3NyOi8vTkRj ...
- jQuery全选全不选
$("[name='goods']").prop("checked", this.checked);
- dprobe and dprofile
https://github.com/xwlan dprofiler Lightweight CPU Memory I/O and Lock profiler for Windows dprobe D ...
- Linux 在VMware中搭建CentOS6.5虚拟机
原文:http://www.cnblogs.com/PurpleDream/p/4263465.html Linux 在VMware中搭建CentOS6.5虚拟机 前言: 本文主要是我在大家 ...
- [NSURL URLWithString:] 返回nil
具体问题原因是url中输入的有中文,那么这个就看作非法的字符无法识别.这种的必须使用post方式来发送消息.具体为: tmp = mainurl; [parameters app ...
- 【jQuery】方法和选择器的双重使用详解
1.jQuery选择直接子节点+除了某个元素 1>方法 $(".begon").children(".row:not(.moreDetail)") 2&g ...
- iOS -- SKSpriteNode类
SKSpriteNode类 继承自 SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) ...
- 为什么硬盘明明还有空间,linux却说硬盘空间不足?inode;mkdir: 无法创建目录"shen1": 设备上没有空间
现象:df -h显示硬盘还有14G空间,但是touch file/mkdir directory都失败,提示硬盘没有空间 原因:df -ia查看下inode的使用情况,发现已经爆了,(下图显示使用88 ...