标准库
regexp
正则表达式
ok,_:=regexp.Match(pat,[]byte(searchIn))
ok,_:=regexp.MatchString(pat,searchIn)
searchIn:="sssssssssssssssssssss"
//Compile
pat:="[0-9]+.[0-9]+"//正则
re,_:=regexp.Compile(pat)
str:=re.ReplaceAllString(searchhIn,"$$.$")
f:=func(s string) string{
v,_:=strconv.ParseFloat(s,32)
return strconv.FormatFloat(v*2,'f',2,32)
}
str2:=re.ReplaceAllStringFunc(searchIn,f)
锁和sync包
当不同线程要使用同一个变量时,无法预知变量被不同线程修改的顺序
- 经典的做法是一次只让一个线程对共享变量进行操作。当变量被一个线程改变时,为它上锁
- Go中通过sync包的Mutex实现
sync.Mutex
是一个互斥锁,作用是守护临界区入口来确保同一时间只能有一个线程进入临界区
import "sync"
type Info struct{
mu sync.Mutex
//... other fields.e.g.:Str string
}
func Update(info *Info){
info.mu.Lock()
info.Str=//new value
info.mu.Unlock()
}
//通过Mutex实现可以上锁的共享缓冲器
type SyncedBuffer struct{
lock sync.Mutex
buffer bytes.Buffer
}
- 还有一个
RWMutex
锁,能通过RLock()来允许同一时间多个线程对变量进行读操作,但只能一个线程进行写操作- 如果用
Lock()
和普通的Mutex作用相同Once
,once.Do(call)
确保被调用函数只能被调用一次
精密计算和big包
- float64,只能精确到15位
- 对超出int64或者unit64类型的大数进行计算,如果对精度没有要求,float32或float64可以胜任,如果对精度有严格要求,不能使用浮点数,在内存中只能被近似的表示
- 对整数的高精度计算提供了big包,其包含了math包:big.Int,big.Rat
- 缺点是更大的内存和处理开销,使用起来慢
big.NewInt(n)
,n为int64big.NewRat(N,D)
,N分子,D分母,都是int64
import {
"fmt"
"math"
"math/big"
}
func main(){
im:=big.NewInt(math.MaxInt64)
in:=im
io:=big.NewInt(1956)
ip:=big.NewInt(1)
ip.Mul(im,in).Add(ip,im).Div(ip,io)
rm := big.NewRat(math.MaxInt64, 1956)
rn := big.NewRat(-1956, math.MaxInt64)
ro := big.NewRat(19, 56)
rp := big.NewRat(1111, 2222)
rq := big.NewRat(1, 1)
rq.Mul(rm, rn).Add(rq, ro).Mul(rq, rp)
}
自定义包和可见性
- 写自己包的时候,要用不含有下划线_的小写单词来为文件命名
- 为了让其他包的文件,可以访问到本包的函数,则该
函数名的首字母需要大写
,类似其他语言的public,这样才能跨包访问- 如果包名较长,Go支持给包取别名,取别名后,原来的包名就不能使用了
import util "xxx/xxx/xxx/utils"
- 同一个包下,不能有相同的函数名(全局变量名)
- 如果要编译程一个可执行程序文件,就需要将这个包声明为main,即package.main,如果写一个库,包名可以自定义
//pack1.go
package pack1
var Pack1Int int=42
var PackFloat=3.14
func ReturnStr() string{
return "Hello main!"
}
import一般格式为:
import “包路径或url路径”
例如:import “github.com/org1/pack1”
//package_test.go
package main
import (
"./pack1"
"fmt"
)
func main(){
var test1 string
test1=pack1.ReturnStr()
}
- 导入外部安装包
- 如果要使用一个或多个外部包,首先要必须使用
go install
在本地机器上安装它们- 如果要使用
http://codesite.ext/author/goExample/goex
这种托管在Google Code、GitHub和Lauchpad等代码托管网站上的包,可以使用
go install codesite.ext/author/goExample/goex
将一个名为“codesite.ext/author/goExample/goex”的map安装在“$GOROOT/src/”目录下
通过以下方式,一次性安装,并导入到代码中:
import goex “codesite.ext/author/goExample/goex”
- 包的初始化
- 程序的执行开始于导入包,初始化main包然后调用main函数
- 一个没有导入的包将通过分配初始值给所有的包级init函数来初始化。
- 一个包可能有多个init函数,甚至可以存在于同一个源码文件中
- 执行是无序的
为自定义包使用godoc
- godoc工具在显示自定义包中的注释也有很好的效果:注释必须以//开始并无空行放在声明前。godoc会给每个文件生成一系列的网页。
- 命令行下进入目录并输入命令:
godoc -http=:6060 -goroot=“.”
"."是当前目录