1.go的函数定义格式为函数名,参数列表, 返回值列表和函数体。如果函数没有返回值,则返回列表可以省略。函数从第一条语句开始执行,直到执行return语句或者执行函数的最后一条语句。
2.函数可以作为参数传递
package main
import (
"fmt"
)
func test(fn func() int) int {
return fn()
}
type formatfunc func(s string, x, y int) string
func format(fn formatfunc, s string, x, y int) string {
return fn(s, x, y)
}
func main() {
s1 := test(func() int { return 100 })
s2 := format(func(s string, x, y int) string {
return fmt.Sprintf(s, x, y)
}, "123", 10, 20)
fmt.Println(s1, s2)
}
3.在默认情况下,go语言使用的是值传递,而map, slice, chan, 指针, interface默认采用引用方式进行传递。
4.Golang 可变参数本质上就是 slice。只能有一个,且必须是最后一个。在参数赋值时可以不用用一个一个的赋值,可以直接传递一个数组或者切片,特别注意的是在参数后加上“…”即可。
func myfunc(args ...int) { //0个或多个参数
}
func add(a int, args…int) int { //1个或多个参数
}
func add(a int, b int, args…int) int { //2个或多个参数
}
注意:其中args是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数.
任意类型的不定参数: 就是函数的参数和每个参数的类型都不是固定的。
func test(s string, n ...int) string {
var x int = 0
for _, i := range n {
x += i
}
return fmt.Sprintf(s, x) //格式化字符串
}
func main() {
println(test("sum: %d", 1, 2, 3))
}
注意,使用slice对象做变参时,必须展开
主函数变为
func main() {
s := []int{1, 2, 3}
res := test("sum: %d", s...) // slice... 展开slice
println(res)
}
5.命名返回参数可被同名局部变量遮蔽,此时需要显式返回。
func add(x, y int) (z int) {
{ // 不能在一个级别,引发 "z redeclared in this block" 错误。
var z = x + y
// return // Error: z is shadowed during return
return z // 必须显式返回。
}
}
6.go语言闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。
“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
package main
import (
"fmt"
)
func a() func() int {
i := 0
b := func() int {
i++
fmt.Println(i)
return i
}
return b
}
func main() {
c := a()
c()
c()
c()
a() //不会输出i
}
函数b嵌套在函数a内部 函数a返回函数b 这样在执行完var c=a()后,变量c实际上是指向了函数b(),再执行函数c()后就会显示i的值,第一次为1,第二次为2,第三次为3,以此类推。 其实,这段代码就创建了一个闭包。因为函数a()外的变量c引用了函数a()内的函数b(),就是说:
当函数a()的内部函数b()被函数a()外的一个变量引用的时候,就创建了一个闭包。 在上面的例子中,由于闭包的存在使得函数a()返回后,a中的i始终存在,这样每次执行c(),i都是自加1后的值。 从上面可以看出闭包的作用就是在a()执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a()所占用的资源,因为a()的内部函数b()的执行需要依赖a()中的变量i。
在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。变量的作用域仅限于包含它们的函数,因此无法从其它程序代码部分进行访问。不过,变量的生存期是可以很长,在一次函数调用期间所创建所生成的值在下次函数调用时仍然存在。正因为这一特点,闭包可以用来完成信息隐藏,并进而应用于需要状态表达的某些编程范型中。 下面来想象另一种情况,如果a()返回的不是函数b(),情况就完全不同了。因为a()执行完后,b()没有被返回给a()的外界,只是被a()所引用,而此时a()也只会被b()引 用,因此函数a()和b()互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。所以直接调用a();是页面并没有信息输出。
下面来说闭包的另一要素引用环境。c()跟c2()引用的是不同的环境,在调用i++时修改的不是同一个i,因此两次的输出都是1。函数a()每进入一次,就形成了一个新的环境,对应的闭包中,函数都是同一个函数,环境却是引用不同的环境。这和c()和c()的调用顺序都是无关的。
标签:闭包,return,函数,int,Day3,func,Go,string,语言 From: https://www.cnblogs.com/kyszdsmz/p/17035129.html