package main
import"fmt"funcmain(){//1.匿名函数var Add =func(a, b int)int{return a + b
}
add :=Add(1,2)//2.多个参数 多个返回值
sum :=sum(1,1,1,1)
fmt.Println(add, sum)//3.当可变参数是一个空接口类型时,调用者是否解包可变参数会导致不同的结果:var a =[]interface{}{123,"abc"}Print(a...)//解包a 等价于 Print(123, "abc") 123 abcPrint(a)//未解包a 等价于 Print([]interface{}{123, "abc"}) [123 abc]//4. 闭包对捕获的外部变量并不是传值方式访问,而是以引用的方式访问。 以下语句将输出 三个 3 因为最后执行时,传进匿名函数的值为3for i :=0; i <3; i++{//defer func() { println(i) }()}//第一种修改方式 正确输出 2 1 0for i :=0; i <3; i++{
a := i //定义一个循环体内部局部变量adeferfunc(){println(a)}()}//第二种修改方式for i :=0; i <3; i++{//通过函数传入i//defer语句会马上对调用参数求值deferfunc(i int){println(i)}(i)}}funcPrint(a ...interface{}){
fmt.Println(a...)}// 多个参数和多个返回值funcSwap(a, b int)(int,int){return b, a
}// 可变数量的参数// more 对应 []int 切片类型funcsum(a int, more ...int)int{for_, v :=range more {
a += v
}return a
}
二、方法
package main
import"fmt"funcmain(){//一、不依赖具体文件对象//方法表达式的特性 不带参数//func Read(f *files) int
Read :=(*files).read
//带参数//func Repeat(f *files,a)
Repeat :=(*files).repeat
var f =&files{x:1, y:1}Read(f)Repeat(f,5)//二、/*不过在方法表达式中,因为得到的 ReadFile 和 CloseFile 函数参数中含有 File 这个特有的类型参数
,这使得 File 相关的方法无法和其它不是 File 类型但是有着相同 Read 和 Close 方法的对象无缝适配。
这种小困难难不倒我们 Go 语言码农,我们可以通过结合闭包特性来消除方法表达式中第一个参数类型的差异*///绑定到了f对象//func Read() intvar ReadF =func()int{return(*files).read(f)}//func RepeatF(a int) intvar RepeatF =func(a int)int{return(*files).repeat(f, a)}
fmt.Println("--------------------")ReadF()RepeatF(6)//三、我们可以用方法值特性简化//方法值:绑定到了 f 对象var ReadM = f.read
var RepeatM = f.repeat
ReadM()RepeatM(8)}type files struct{
x int
y int}func(r *files)read()int{
fmt.Println(r.x, r.y)
fmt.Println("this is read method")return r.x + r.y
}func(r *files)repeat(a int)int{
fmt.Println(a, r.x)
fmt.Println("this is repeat method")return a + r.x
}
三、接口
package main
import("fmt""strings")type UpString stringfuncmain(){//对于每个要打印的对象,如果满足了 fmt.Stringer 接口,则默认使用对象的 String 方法返回的结果打印:
s := UpString.String("123","abcderg")
fmt.Println(s)}func(r UpString)String(str string)string{return strings.ToUpper(str)}