go 杂项笔记
***
使用go build编译该程序,注意这里需要指定 -gcflags "-N -l" 关闭编译器优化,否则编译器可能把对sum函数的调用优化掉。
bobo@ubuntu:~/study/go$ gobuild -gcflags"-N -l"sum.go
***
go fmt命令——格式化代码文件
https://studygolang.com/articles/18538?fr=sidebar
***
通道-chan
发送端关闭通道,而不应该在接收端关闭通道,否则会引起panic
***
通道的特性就是它的自同步和其元素值的原子性。
在 go 语言的并发程序中,通道会成为联系各个Goroutine的纽带。
在需要循环的接收通道中的元素值的场景下,应该优先使用 for 语句来实现:
var ch chan int
if ch != nil{
for ch != range ch {
fimt.Printf("Element: %v\n",e)
}
}
select 语句中,default case 会在收发操作无法配对的情况下被选中并执行。
代码包 time 中的定时器(time.Timer)和 断续器(time.Ticker)都充分利用了缓冲通道的异步特性来传达到期事件。
*** 锁
go 语言中,死锁错误的发生几率极低。其主要原因是有defer 语句的存在。
在 Go 语言中,读写锁有结构体类型 sync.RWMutex 代表。与互斥锁类似,sync.RWMutex类型的零值就已经是立即可用的读写锁了。在此类型的方法集合中包含了两对方法,即:
func (*RWMutex) Lock
func (*RWMutex) Unlock
和
func (*RWMutex) RLock
func (*RWMutex) RUnlock
前一对方法的名称和签名与互斥锁的那两个方法完全一致。它们分别代表了对写操作的锁定和解锁。以下简称它们为写锁定和写解锁。
而后一对方法则分别表示了对读操作的锁定和解锁,以下简称它们为读锁定和读解锁。
写解锁在进行的时候会试图唤醒所有因欲进行读解锁而被阻塞的Goroutine。而读解锁在进行的时候只会在已无任何读锁定的情况下试图唤醒一个因欲进行写锁定而被阻塞的Goroutine。若对一个未被写锁定的读写锁进行解锁,就会引起一个运行时恐慌,而对一个未被读锁定的读写锁进行读解锁不会发生 panic。
原则上,不应该把通道当作互斥锁或信号灯来使用。
《effective go》
gofmt 格式化 go 源文件
go 文件注释:
------------------------------------------------------------------------------------------------------
/*
regexp 包为正则表达式实现了一个简单的库。
该库接受的正则表达式语法为:
正则表达式:
串联 { '|' 串联 }
串联:
{ 闭包 }
闭包:
条目 [ '*' | '+' | '?' ]
条目:
'^'
'$'
'.'
字符
'[' [ '^' ] 字符遍历 ']'
'(' 正则表达式 ')'
*/
package regexp
------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
在程序中,每个可导出(首字母大写) 的名称都应该有文档注释。
------------------------------------------------------------------------------------------------------
命名:
大写首字母,包外可见。
包应当以小写的单个单词来命名,且不应该使用下划线或驼峰记法。
获取器:若你有个名为 owner (小写,未导出) 的字段,其获取器应当名为 Owner(大写,可导出) 而非 GetOwner。 设置器方法,SetOwner .
Go 中约定使用驼峰记法(匈牙利命名法) MixedCaps 或 mixedCaps 。
以指针或值为接收者的区别在于:值方法可通过指针和值调用,而指针方法只能通过指针来调用。
若该值是可寻址的, 那么该语言就会自动插入取址操作符来对付一般的通过值调用的指针方
法。在我们的例子中,变量 b 是可寻址的,因此我们只需通过 b.Write 来调用它的 Write 方
法,编译器会将它重写为 (&b).Write
用空白标识符声明一个全局变量:
var _ json.Marshaler = (*RawMessage)(nil)
检测json.Marshaler 的实现情况。