@ -0,0 +1,11 @@ | |||||
# 函数声明 | |||||
在go中所有函数都必须声明在包级别代码块中,或者说任何一个函数都不能声明在另一个函数体内 | |||||
虽然匿名函数可以定义在函数体内,但是匿名函数定义不属于函数声明 | |||||
# 函数的退出阶段 | |||||
一个函数从返回开始到最终退出的阶段称为此函数的退出阶段 exiting phase | |||||
函数退出阶段的意义??? | |||||
# 匿名函数 | |||||
注意匿名函数定义不是一个函数声明 |
@ -0,0 +1,24 @@ | |||||
# 代码包和包引入 | |||||
go使用代码包 package 来组织管理代码 | |||||
# 代码包目录 代码包引入路径和代码包依赖关系 | |||||
# init函数 | |||||
在一个代码包中 甚至一个源文件中可以声明若干名为init | |||||
的函数,这些init函数必须不带任何输入参数和返回结果 | |||||
注意: 我们不能数据声明为init的包级变量 常量或者类型 | |||||
在程序运行时刻, 在进入main入口函数之前,每个init函数(可以在一个包中声明多个)在此包加载的时候被串行执行并且只执行一次 | |||||
# 程序资源初始化顺序 | |||||
一个程序中所涉及到的所有的在运行时刻要用到的代码包的加载是串行执行的。 在一个程序启动时, 每个包中总是在它所有依赖的包都加载完成之后才开始加载。 程序代码包总是最后一个被加载的代码 包。每个被用到的包会被而且仅会被加载一次。 | |||||
在同一个源文件中声明的init函数将按从上到下的顺序被调用执行。 对于声明在同一个包中的两个不 同源文件中的两个init函数,Go语言白皮书推荐(但不强求)按照它们所处于的源文件的名称的词典 序列(对英文来说,即字母顺序)来调用。 所以最好不要让声明在同一个包中的两个不同源文件中的 两个init函数存在依赖关系。 在加载一个代码包的时候,此代码包中声明的所有包级变量都将在此包中的任何一个init函数执行之 前初始化完毕。 在同一个包内,包级变量将尽量按照它们在代码中的出现顺序被初始化,但是一个包级变量的初始化肯 定晚于它所依赖的其它包级变量。 比如,在下面的代码片段中,四个包级变量的初始化顺序依次 为y、z、x、w。 | |||||
# 完整的引入声明语句的形式 | |||||
import importname "path/to/package" | |||||
importname是可选的 它的默认值为被引入的包的包名 | |||||
@ -0,0 +1,17 @@ | |||||
package main | |||||
type Val struct { | |||||
Name string | |||||
Age int | |||||
} | |||||
func NewValue(name string, age int) *Val { | |||||
c := new(Val) | |||||
c.Name = name | |||||
c.Age = age | |||||
return c | |||||
} | |||||
func main() { | |||||
NewValue("Test", 10) | |||||
} |
@ -0,0 +1,23 @@ | |||||
package main | |||||
import "fmt" | |||||
func init() { | |||||
fmt.Printf("IMY*************11111") | |||||
} | |||||
func init() { | |||||
fmt.Printf("IMY*************222") | |||||
} | |||||
func init() { | |||||
fmt.Printf("IMY*************3333") | |||||
} | |||||
func init() { | |||||
fmt.Printf("IMY*************44444") | |||||
} | |||||
func main() { | |||||
fmt.Printf("IMY*************main") | |||||
} |
@ -0,0 +1,75 @@ | |||||
package main | |||||
import ( | |||||
"fmt" | |||||
"os" | |||||
"runtime/trace" | |||||
"testing" | |||||
) | |||||
type Small struct { | |||||
a, b, c int64 | |||||
d, e, f string | |||||
g, h, i float64 | |||||
} | |||||
func value() Small { | |||||
return Small{ | |||||
a: 1, b: 1, c: 1, | |||||
d: "test", e: "hello", f: "world", | |||||
g: 1.0, h: 2.222222, i: 66.666666, | |||||
} | |||||
} | |||||
func ptr() *Small { | |||||
return &Small{ | |||||
a: 1, b: 1, c: 1, | |||||
d: "test", e: "hello", f: "world", | |||||
g: 1.0, h: 2.222222, i: 66.666666, | |||||
} | |||||
} | |||||
func BenchmarkMemoryStack(b *testing.B) { | |||||
var s Small | |||||
f, err := os.Create("stack.out") | |||||
if err != nil { | |||||
panic(err) | |||||
} | |||||
defer f.Close() | |||||
err = trace.Start(f) | |||||
if err != nil { | |||||
panic(err) | |||||
} | |||||
for i := 0; i < b.N; i++ { | |||||
s = value() | |||||
} | |||||
trace.Stop() | |||||
b.StopTimer() | |||||
_ = fmt.Sprintf("%v", s.a) | |||||
} | |||||
func BenchmarkHeap(b *testing.B) { | |||||
var s *Small | |||||
f, err := os.Create("heap.out") | |||||
if err != nil { | |||||
panic(err) | |||||
} | |||||
defer f.Close() | |||||
err = trace.Start(f) | |||||
if err != nil { | |||||
panic(err) | |||||
} | |||||
for i := 0; i < b.N; i++ { | |||||
s = ptr() | |||||
} | |||||
trace.Stop() | |||||
b.StopTimer() | |||||
_ = fmt.Sprintf("%v", s.a) | |||||
} |