var name type
// 一次声明多个同一类型的变量
var a, b int
// 批量声明变量
var (
a int
b string
c []float32
d func() bool
e struct {
x int
}
)
// 声明变量并赋值
var a int = 10
// 声明变量但是没有初始化的,将会赋予指定数据类型
var b int // b = 0
// 变量类型自动推断
var age = 100 // 自动推断为int
fmt.Println("type=", reflect.TypeOf(age))
// := 简短声明
age := 10 // 自动推断类型为int
// 多变量赋值,a b 变量交换
var a int = 100
var b int = 200
b, a = a, b
fmt.Println(a, b)
package main
import "fmt"
// 本函数测试入口参数和返回值情况
func dummy(b int) int {
// 声明一个变量c并赋值
var c int
c = b
return c
}
// 空函数, 什么也不做
func void() {
}
func main() {
// 声明a变量并打印
var a int
// 调用void()函数
void()
// 打印a变量的值和dummy()函数返回
fmt.Println(a, dummy(0))
}
使用如下命令对上面代码进行内存分析:
# -m 内存分配分析
# -l 避免程序内联,也就是避免程序进行优化
go run -gcflags "-m -l" main.go
# command-line-arguments
./main.go:19:13: ... argument does not escape
./main.go:19:13: a escapes to heap # 变量a逃逸到了堆
./main.go:19:22: dummy(0) escapes to heap # dumy(0)的返回值逃逸到了堆
变量逃逸分析:取地址符
package main
import "fmt"
// 声明空结构体测试结构体逃逸情况
type Data struct {
}
func dummy() *Data {
// 实例化c为Data类型
var c Data
//返回函数局部变量地址
return &c
}
func main() {
fmt.Println(dummy())
}
执行go run -gcflags "-m -l" main.go的结果:
# command-line-arguments
./main.go:8:6: moved to heap: c # 变量c在第八行的位置,因为使用&取地址符,为了保证程序的最终运行结果,所以将变量c从栈转移到了堆空间中
./main.go:13:13: ... argument does not escape
&{}