Go基础-012 标识符作用域与闭包

2020-02-24  本文已影响0人  如逆水行舟不进则退

1. 作用域

标识符的可见性。主要是变量,常量。当定义好标识符(变量)后,在什么位置可以使用。就是作用域 scope 的问题。

作用域主要点:

2.闭包现象

closure
当作用域是嵌套情况下时(go 语言就是嵌套的),内层作用域(语句块)使用外层作用域的变量,当外层语句块运行结束后,如果内层语句块还可以被使用,则内层语句块与外层 变量构成了闭包。闭包现象会导致,外层语句中定义的变量,不会立即被释放。

演示:

func outer() func() { 
  n := 42
  return func() {
      n ++ // 使用外层变量
      fmt.Println(n) 
    }
 }
  f := outer()
  // outer()运行结束,外层语句块 
  f() // 42

上面的代码中,内层函数就与外层 outer()定义的变量 n 形成了闭包,n 不会随着 outer()的运 行结束而释放。
Go 语言支持闭包!没有好坏!

闭包,将一组数据和一些操作组合在了一起,也被称作带有数据的操作。(面向对象编程,
带有操作的数据),体现了数据的实体性。

由于闭包可以将数据和操作绑定在一起,完成一些特定的封装业务逻辑,演示做一个计数器, 使用全局变量的方案:

// 全局变量 counter 用于计数
var counter = 0
func CounterIncr() {
  counter ++ 
}
func CounterDecr() {
  counter -- 
}

该方案致命的问题是,counter 这个变量,不仅仅 CounterIncr() CunterDecr()可用,任何代码 都可用,不能保证 couter 变量的准确性。如何才能将 counter 与具体的操作函数绑定在一起 呢?只能某些个函数可以操作 counter。
利用闭包来实现,利用闭包来实现封装的计数器。

func CounterInit(initValue int) (func(), func(), func() int) {
 counter := initValue
  return func() {
      counter ++ 
  }, func() {
      counter -- 
  }, func() int {
       return counter
  } 
}
CounterIncr, CounterDecr, CounterGetter := CounterInit(0) 
fmt.Println(CounterGetter())
CounterIncr()
CounterIncr()
CounterDecr() 
fmt.Println(CounterGetter())
上一篇 下一篇

猜你喜欢

热点阅读