在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1,函数1.1 函数的定义Go支持匿名函数和闭包,Go的函数类似Python可以返回多个值。Go也是静态编译型的语言。先来看看Go的函数定于格式: func 函数名(参数表...) [(返回值...)] {
//函数体
}
注意: 1,返回值在参数表后定义,如果只有一个返回值,那么返回值两边的括号是不要的,如果没有返回值那么返回值这一项可以省略。 2,函数体的开始大括号必须在行尾,这是强制的,类似的if, switch中的也是如此。 3,如果函数名大写字母开头,那么就是对外可见的(exported, public)。如果是小写字母那么就是包内(package level)私有的。 1.2 成员函数定义func (t *type) 函数名(参数表...) [(返回值...)] {
//函数体
}
这样就可以为type定义一个成员函数了。 1.3 函数的嵌套你可以在一个函数体内定义匿名函数甚至你可以定义匿名函数,然后用变量去引用这个匿名函数。但是你不可以在函数体内嵌套定义一个具名函数。 func main() {
func () {
fmt.Println("anonymous func is ok")
}()
var foo = func () {
fmt.Println("using a variable to refer anonymous func is ok")
}
foo()
func notAllow() {
fmt.Println("you can not define named func")
}
}
匿名函数在这里有值(value type)的语义。你可以像对待一个值那样去对待匿名函数(当参数传递,作为函数返回值)。但是具名函数不享有这种优待。相对于JavaScript或Lisp这样的语言,他缺少了“可以在任意位置定义函数”的能力。在Go中,匿名函数有这种能力。 2,构建系统(build)2.1 GOPATH当前的项目目录要添加到GOPATH中,你可以用$go env来检查你当你的环境变量,包括GOPATH。 如果,你想列出当前目录下所有的包(packages),可以使用
当你GOPATH设置过了以后,你所有以go开头的命令,都是以GOPATH指定的项目目录为起始目录的。 比如:
3,三个点(…)对于定义不定参数数量的函数需要三个点…: func(a, b int, z float64, opt ...interface{})
最后一个为任意类型的的不定参数,用…来标明。 还有个时常用到…的地方是对数组切片添加元素,当添加的元素是数组或数组切片类型的,append(arr, …T)需要将元素“打散”以当做不定参数来传递,这时也要用到…: s2 := append(s1, 3, 5, 7) //一个一个传递
s3 := append(s2, s0...) //将数组“打散传递”
4,goroutinegoroutine是Go语言在语言级别对并发的支持。并发执行体的粒度从系统到轻量级线程分别有:进程,线程,轻量级线程。goroutine应该算是轻量级线程,在我的电脑上(Win7, Intel i7)可以在3s内创建大约300,000个goroutine。 对于并发来说最大的问题是同步和通信,在Go语言中同步和通信是通过语言内置的channel来近乎完美解决的。channel不仅仅是goroutine通信的方式,也通过自动阻塞这种方式达到了同步的目的。channel可以作为函数的参数传来传去,channel这个参数在使用上像一个引用类型。他可以跨“函数”传递消息。然而实际上他是值类型,channel是函数通信的边界,你不能通过channel来执行还有副作用的赋值操作——当然,除了你通过传递一个指针硬要这么做。 package main
import "fmt"
func intGenerator(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i //pass the i to the channel
}
close(ch) //close the channel
}
func main() {
var ch chan int = make(chan int)
go intGenerator(ch)
for {
val, ok := <-ch //if channel closed, the ok will be false
if ok {
fmt.Println(val)
} else {
return
}
}
}
|
请发表评论