目录
1.函数
如下函数使用func标识,包含函数签名和函数体。
func name(parameter-list) (result-list) {
body
}
func hypot(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
1.1 函数声明
函数包含签名和函数体,函数体很好理解,就是语句的集合
签名包含func、函数名、参数列表、返回值,与其它语言类似,比较明显的区别有两个
- 参数列表的参数名、参数类型的声明顺序,且相同类型可以简写
- 返回值是个列表,长度是[0,n],可以没有返回值(类似java void),也可有多个返回值;可以命名如下z
- 函数传参是值传递,传入拷贝的值,只有指针, slice, map, function, channel这5个引用类型修改在函数外有效,其余都无效
func add(x int, y int) int { return x + y }
func sub(x, y int) (z int) { z = x - y; return }
func first(x int, _ int) int { return x }
func zero(int, int) int { return 0 }
1.1.1 第三方类库
函数就是为了复用,go团队在golang.org/x/仓库中提供了大量的非标准包,为什么不将它们放在标准库中呢?有的因为还在开发阶段,有的因为只有少部分人需要引用。
go get等获取golang.org/x/下的包一般会报错,因为外网防火墙的原因,所以一般从对应的github仓库将其下载到本地${ GOPATH}/src/golang.org/x下,类似于maven的远程仓库和本地仓库,如下命令
# golang.org
git clone git@github.com:golang/net.git ${GOPATH}/src/golang.org/x/net
1.2 函数调用&递归
与大多数语言语法类似,如下,html是引入的包,Parse是export导出的方法,参数是标准输入,返回值赋值给doc和err。
doc, err := html.Parse(os.Stdin)
与大多数语言类似,支持递归,递归就是直接或者间接地调用自身,使用场景如树的深度遍历等等。
与大多数语言递归不同的时,很多语言如Java有栈大小(64KB-2MB)的限制,递归深度过大可能抛出栈溢出的异常,(通常是因为递归边界没有写好),但是Go的栈大小是可以动态增长地,一直到GB级别的大小。所以在递归时要更加注意边界,否则可能侵占更多资源,更长时间才能发现!!
1.3 返回值
Go可以有多个返回值,约定俗成的是一般函数调用返回结构和是否成功的标识符。如果不是以上的惯例需要通过函数命名传达返回值有几个、什么含义。
return result, nil // return语句
resp, err := http.Get(url) // 调用,返回值赋值
links, _ := findLinks(url) // errors ignored ,如果不需要某个返回值,需要将其赋值给_
1.4.1 命名返回值
如果返回值有了名字,则可以省略return语句后面的变量(裸return),因为其作为局部变量在函数被使用了。
func CountWordsAndImages(url string) (words, images int, err error) {
resp, err := http.Get(url)
if err != nil {
return
}
doc, err := html.Parse(resp.Body)
resp.Body.Close()
if err != nil {
e