“这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战
包概述
- 包(package)是Go语言中组织单元.包是逻辑上的分组.而物理上的分组是不同的文件夹,文件夹和包一般是对应的
- 把多个文件放入同一个文件夹中,这些文件就是在同一个包中.
- 虽然允许源码文件的package和文件夹名不同但是最终编译后都会把文件的package编译成文件夹名称.所以为防止错误最好把文件的package和文件夹名称设置成相同的
- 一个Go语言项目必须要有main包,其他自定义名称的包个数任意,根据自己的需求即可.
- Go语言在寻找包时会从GOPATH/src 路径中寻找包,如果不存在去GOROOT/src(Go语言标准库源码所在文件夹)下找
- 不同包下资源可以相互访问,在导入其他包后,可以访问包下首字母大写的内容
- 同包下不同文件中全局资源可以随意访问
自定义包
- 新建项目后在项目下新建src文件夹,在src文件夹中新建demo文件
- 在demo文件中新建demo1.go和demo2.go文件
- demo1.go文件源码如下
package demo//包为demo
import "fmt"
func demo1(){
fmt.Println("执行demo1")
}
复制代码
- demo2.go文件源码如下
package demo//包为demo
import "fmt"
func Demo2() {//函数名大写才能被其他包访问
fmt.Println("执行demo2")
demo1()//同包下内容任意访问
}
复制代码
- 在项目根目录下新建main.go,源码如下
package main
import "demo"
func main() {
demo.Demo2()
}
复制代码
- 运行整个项目后,发现可以正常调用Demo2()函数
- 整个程序目录结构如下
变量作用域
- 变量声明位置决定了变量的可访问范围(哪里能调用到变量)
- Go语言中变量的有效范围如下
- 函数级别:变量声明在函数内部,只有在函数内部才能访问,称变量为局部变量
- package 包级别,在当前包下都可以访问.称变量为全局变量.变量声明在函数外面
- 应用级别,在整个应用下任何包内都可以访问.通过首字母大小写控制
局部变量
- 局部变量一定是在函数内部
- 在哪个{}内部声明,只能在哪个{}内部访问
func test1() {
i := 2 //从此处开始到test1结束}任何位置都能调用i
if i>=2{
j:=3
fmt.Println(i+j)//此处可以访问i
}
fmt.Println(i)
//fmt.Println(j)//此处不能调用j,超出声明j时{}外
}
func test2() {
fmt.Println(i) //此处无法调用test1()中的i
}
复制代码
全局变量
- 全局变量声明到函数外部,整个包都可以访问
- 如果全局变量首字母大写,跨包也可以访问.
- 声明全局变量时规范是
var (
变量名
变量名=值
)
复制代码
- 全局变量代码示例
var (
name = "smallming"
age = 17
)
func demo1() {
fmt.Println("名字:",name)
}
func demo2() {
fmt.Println("年龄:",age)
}
复制代码
闭包概述
- 闭包不是Go语言独有的概念,在很多编程语言中都有闭包
- 闭包就是解决局部变量不能被外部访问一种解决方案
- 是把函数当作返回值的一种应用
代码演示
- 总体思想为:在函数内部定义局部变量,把另一个函数当作返回值,局部变量对于返回值函数就相当于全局变量,所以多次调用返回值函数局部变量的值跟随变化
package main
import "fmt"
func main() {
//res其实就是test1返回值函数,和之前匿名函数变量一个道理
res := test1()
fmt.Println(res()) //输出2
fmt.Println(res()) //输出3
fmt.Println(res()) //输出4
}
//注意此处,返回值类型是func int
func test1() func() int {
i := 1
return func() int {
i = i + 1
return i
}
}
复制代码
- 如果重新调用test1()会重新声明及赋值局部变量i
package main
import "fmt"
func main() {
f := test1()
fmt.Println("f的地址", f) //输出匿名函数地址
fmt.Println("f:", f()) //调用匿名函数输出2
fmt.Println("f:", f()) //调用匿名函数输出3
k := test1()
fmt.Println("k的地址", k) //输出匿名函数地址,与f相等
fmt.Println("k:", k()) //调用匿名函数输出2
fmt.Println("f:", f()) //输出:4
fmt.Println("k:", k()) //输出:3
}
func test1() func() int {
i := 1
return func() int {
i++
// 每调用一次test1()输出的地址不一样
fmt.Println("i的地址:", &i)
return i
}
}
复制代码
近期评论