Go 语言
变量的作用域
变量的生存周期:
包一级声明的变量,生存期和整个程序运行周期一致
局部变量,从该变量声明开始,到该变量不再被引用,被自动回收后结束
函数是可以返回局部变量的,因为
Go
编译器会将返回到函数外的局部变量存储在heap
上。实际上所有变量都是由Go
编译器决定存储在heap
或是stack
,这个称为变量逃逸分析。
var cwd string
func init() {
// 写法1
cwd, err := os.Getwd() // 这里的 cwd 是新建的,就不是全局变量
// 写法2
var err error
cwd, err = os.Getwd() // 这里的 cwd 就是全局变量
if err != nil {
log.Fatalf("os.Getwd faild: %v", err)
}
log.Printf("Working directory = %s", cwd)
}
func main() {
fmt.Printf("cwd : %s", cwd)
}
# 变量逃逸分析
# -m 表示进行内存分配分析
# -l 表示避免程序内联,也就是避免进行程序优化
$ go run -gcflags "-m -l" cky.go
var a string // 全局变量
func main() {
a = "G"
print(a) // G
f1()
}
func f1() {
a := "O"
print(a) // O
f2()
}
func f2() {
print(a) // G 思考下,f2 在 f1 里调用,为啥 a 不是 0 呢 ?
}
指针
Go
指针 最大的特点就是取消了 指针运算,其他方面和 C
差不多。
i := 42 // 普通变量
var p *int; // 声明 int 指针
p = &i // p 指向 i
*p = 21 // 通过 p 改变 i
fmt.Println( *p ); // 通过 p 访问 i
模拟枚举
type ChipType int // 声明芯片类型
const (
None ChipType = iota
CPU // 中央处理器
GPU // 图形处理器
)
func (c ChipType) String() string {
switch c {
case None:
return "None"
case CPU:
return "CPU"
case GPU:
return "GPU"
}
return "N/A"
}
func main() {
fmt.Printf("%s %d", CPU, CPU) // 输出CPU的值并以整型格式显示
}