• 104157

    文章

  • 803

    评论

  • 12

    友链

  • 比来新加了换肤功能,大年夜家多来走走吧~~~~
  • 爱好这个网站的同伙可以加一下QQ群,我们一路交换技巧。

18. 懂得Go 说话中的 语句块与感化域

撸了本年阿里、腾讯和美团的面试,我有一个重要发明.......>>

Hi,大年夜家好,我是明哥。

在本身进修 Golang 的这段时间里,我写了详细的进修笔记放在我的小我微信公众号 《Go编程年光》,关于 Go 说话,我也算是个初学者,是以写的器械应当会比较合适刚接触的同窗,假设你也是刚进修 Go 说话,不防存眷一下,一路进修,一路生长。

我的在线博客:http://golang.iswbm.com 我的 Github:github.com/iswbm/GolangCodingTime


由于 Go 应用的是词法感化域,而词法感化域依附于语句块。所以在讲感化域时,须要先懂得一下 Go 中的语句块是怎样一回事?

1. 显示语句块与隐式语句块

浅显地说,语句块是由花括弧({})所包含的一系列语句。

语句块外部声明的名字是没法被外部块拜访的。这个块决定了外部声明的名字的感化域范围,也就是感化域。

用花括弧包含的语句块,属于显示语句块。

在 Go 中还有很多的隐式语句块:

  • 主语句块:包含一切源码,对应内置感化域
  • 包语句块:包含该包中一切的源码(一个包能够会包含一个目次下的多个文件),对应包级感化域
  • 文件语句块:包含该文件中的一切源码,对应文件级感化域
  • for 、if、switch等语句本身也在它本身的隐式语句块中,对应部分感化域

前面三点好懂得,第四点举几个例子

for 轮回完后,不克不及再应用变量 i

for i := 0; i < 5; i++ {
    fmt.Println(i)
}

if 语句断定完后,异样不克不及再应用变量 i

if i := 0; i >= 0 {
    fmt.Println(i)
}

switch 语句完了后,也是否是再应用变量 i

switch i := 2; i * 4 {
case 8:
    fmt.Println(i)
default:
    fmt.Println(“default”)
}

且每个 switch 语句的子句都是一个隐式的语句块

switch i := 2; i * 4 {
case 8:
    j := 0
    fmt.Println(i, j)
default:
    // "j" is undefined here
    fmt.Println(“default”)
}
// "j" is undefined here

2. 四种感化域的懂得

变量的声明,除声明其类型,其声明的地位也有讲究,不合的地位决定了其具有不合的感化范围,说白了就是我这个变量,在哪里可用,在哪里弗成用。

根据声明地位的不合,感化域可以分为以下四个类型:

  • 内置感化域:不须要本身声明,一切的关键字和内置类型、函数都具有全局感化域
  • 包级感化域:必須函数外声明,在该包内的一切文件都可以拜访
  • 文件级感化域:不须要声明,导入便可。一个文件中经过过程import导入的包名,只在该文件内可用
  • 部分感化域:在本身的语句块内声明,包含函数,for、if 等语句块,或自定义的 {} 语句块构成的感化域,只在本身的部分感化域内可用

以上的四种感化域,从上往下,范围从大年夜到小,为了表述便利,我这里本身将范围大年夜的感化域称为高层感化域,而范围小的称为低层感化域。

关于感化域,有以下几点总结:

  • 低层感化域,可以拜访高层感化域
  • 同一层级的感化域,是相互隔离的
  • 低层感化域里声明的变量,会覆盖高层感化域里声明的变量

在这里要留意一下,不要将感化域和生命周期混为一谈。声明语句的感化域对应的是一个源代码的文本区域;它是一个编译时的属性。

而一个变量的生命周期是指法式榜样运转时变量存在的有效时间段,在此时间区域内它可以被法式榜样的其他部分援用;是一个运转时的概念。

3. 静态感化域与静态感化域

根据部分感化域内变量的可见性,能否是静态不变,可以将编程说话分为以下两种:

  • 静态感化域,如 Go 说话
  • 静态感化域,如 Shell 说话

详细甚么是静态感化域,这里用 Shell 的代码演示一下,你就知道了

#!/bin/bash
func01() {
    local value=1
    func02
}
func02() {
    echo "func02 sees value as ${value}"
}

# 履行函数
func01
func02

从代码中,可以看到在 func01 函数中定义了个部分变量 value,按理说,这个 value 变量只在该函数内可用,但由于在 shell 中的感化域是静态的,所以在 func01中也能够调用 func02 时,func02 可以拜访到 value 变量,此时的 func02 感化域可以当作是 部分感化域中(func01)的部分感化域。

但如果离开了 func01的履行情况,将其放在全局情况下或许其他函数中, func02 是拜访不了 value 变量的。

所以此时的输入成果是

func02 sees value as 1
func02 sees value as 

但在 Go 中其实不存在这类静态感化域,比如这段代码,在func01函数中,要想取得 name 这个变量,只能从func01的感化域或许更高层感化域里查找(文件级感化域,包级感化域和内置感化域),而不克不及从调用它的另外一个部分感化域中(由于他们在层级上属于同一级)查找。

import "fmt"

func func01() {
	fmt.Println("在 func01 函数中,name:", name)
}

func main()  {
	var name string = "Python编程年光"
	fmt.Println("在 main 函数中,name:", name)

	func01()
}

是以你在履行这段代码时,会报错,提示在func01中的name还未定义。

参考文章:https://studygolang.com/articles/12632

系列导读

01. 开辟情况的搭建(Goland & VS Code)

02. 进修五种变量创建的办法

**03. 详解数据类型:**整形与浮点型

04. 详解数据类型:byte、rune与string

05. 详解数据类型:数组与切片

06. 详解数据类型:字典与布尔类型

07. 详解数据类型:指针

08. 面向对象编程:构造体与持续

09. 一篇文章懂得 Go 里的函数

10. Go说话流程控制:if-else 条件语句

11. Go说话流程控制:switch-case 选择语句

12. Go说话流程控制:for 轮回语句

13. Go说话流程控制:goto 无条件跳转

14. Go说话流程控制:defer 延迟调用

15. 面向对象编程:接口与多态

16. 关键字:make 和 new 的差别?

17. 一篇文章懂得 Go 里的语句块与感化域

18. 进修 Go 协程:goroutine

19. 进修 Go 协程:详解信道/通道

20. 几个信道逝世锁经典缺点案例详解

21. 进修 Go 协程:WaitGroup

22. 进修 Go 协程:互斥锁和读写锁

23. Go 里的异常处理:panic 和 recover

24. 超详细解读 Go Modules 前世此生及入门应用

25. Go 说话中关于包导入必学的 8 个知识点

26. 若何开源本身写的模块给他人用?

27. 说说 Go 说话中的类型断言?

28. 这五点带你懂得Go说话的select用法



695856371Web网页设计师②群 | 爱好本站的同伙可以收藏本站,或许参加我们大年夜家一路来交换技巧!

0条评论

Loading...


自定义皮肤 主体内容背景
翻开付出宝扫码付款购买视频教程
碰到成绩接洽客服QQ:419400980
注册梁钟霖小我博客