go里面函数是一等公民,可以作为参数,变量,返回值。 可实现高阶函数和闭包等功能
闭包实现求和方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| func adder() func(int) int { sum := 0 return func(val int) int { sum += val return sum } }
type iAdder func(int) (int, iAdder)
func adder2(base int) iAdder { return func(val int) (int, iAdder) { return base + val, adder2(base + val) } }
func main() { add := adder() for i := 1; i < 10; i++ { fmt.Printf("0 - %d 的和为:%d \n", i, add(i)) } }
|
菲波那切数列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| func fabnqie() intGen { a, b := 0, 1 return func() int { a, b = b, a+b return a } }
type intGen func() int
func (g intGen) Read(p []byte) (n int, err error) { next := g() if next > 10 { return 0, io.EOF } s := fmt.Sprintf("%d\n", next) return strings.NewReader(s).Read(p) }
func printContent(reader io.Reader) { scanner := bufio.NewScanner(reader) for scanner.Scan() { fmt.Println(scanner.Text()) } }
func main(){ f := fabnqie() printContent(f) }
|
方法表达式
instance.method(args…) —> .func(instance, args…)
前者称为 method value,后者 method expression。
两者都可像普通函数那样赋值和传参,区别在于 method value 绑定实例,而 method expression 则须显式传参。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| type User struct { id int name string }
func (self *User) Test() { fmt.Printf("%p, %v\n", self, self) }
func main() { u := User{1, "Tom"} u.Test()
mValue := u.Test mValue()
mExpression := (*User).Test mExpression(&u)
u2 := User{1, "Tom"} m2Value := u.Test
u2.id, u2.name = 2, "Jack" u2.Test()
m2Value() }
|
在汇编层面,method value 和闭包的实现方式相同,实际返回 FuncVal 类型对象。
学习两种赋值方式
1 2 3 4
| a := (*interface{})(nil)
var c interface{} c = (*interface{})(nil)
|
a现在是啥?
(*interface{})(nil) 意思是把nil 类型转换为 *interface{}类型
a相当于 var a *interface{} = nil
a是个指针, 指向了nil, 所以a是nil
c现在是啥 ?
c是 interface{} 类型 , 这个类型有两个属性 , type和data,
c的type属性是*interface{},有值
c的data属性是nil,无值
只有当type和data都是nil时, 空接口才是nil, 所以c不是nil
1 2 3 4 5
| a := (*interface{})(nil) log.Printf("%v\n", a == nil) var c interface{} c = (*interface{})(nil) log.Printf("%v\n", c == nil)
|