# Go语言的程序结构 #
***
## 命名规则
**Go 语言的命名规则和C语言的命令没什么不同,都是由数字,下划线,字母组成,且必须以下划线或者字母开头。大小写敏感(var a int 和 var A int是不同变量)**
GO语言的关键字主要包括25个:
<table class="table table-bordered table-striped table-condensed">
<tr>
<td>break</td>
<td>default</td>
<td>func</td>
<td>interface</td>
<td>select</td>
</tr>
<tr>
<td>case</td>
<td>defer</td>
<td>go</td>
<td>map</td>
<td>struct</td>
</tr>
<tr>
<td>chan</td>
<td>else</td>
<td>goto</td>
<td>package</td>
<td>switch</td>
</tr>
<tr>
<td>const</td>
<td>fallthrough</td>
<td>if</td>
<td>range</td>
<td>type</td>
</tr>
<tr>
<td>continue</td>
<td>for</td>
<td>import</td>
<td>return</td>
<td>var</td>
</tr>
</table>
**如果一个变量是在函数内部定义的,那么只能函数内部访问,这个C语言的局部变量是一个概念,go语言的包一般采用小写,对于封装问题,如果你想将某个函数暴露给外面,那么函数名字首字母需要大写,如果不想那么函数名字是小写。就像fmt包里面的Println()函数。**
Go 语言的一般采用 **驼峰式** 赋值,也就是一般采用大小写间隔而不用_来隔开单词。
eg: parseMemoryAllocate.
***
##变量定义
### 变量 ###
Go 语言的变量的定义是跟其它语言很不同的,GO语言的变量定义格式如下:
var 变量名字 数据类型 = 表达式
其中 数据类型,=表达式 可以去掉其中之一,当去掉数据类型的时候,变量会根据后面的表达式的值来推导变量类型,去掉=表达式的时候,会采用系统的默认的值。
var a,b,c = 3.14,3,true (a是float,b是int,c是bool)
var a,b,c int (a,b,c默认值都是0)
### 简短变量 ###
简短变量的定义是一个很方便的功能,它的结构如下
名字 := 表达式
简短变量定义方便简洁,被广泛的应用在了大部分的局部变量的声明和初始化中。**var 的定义方法一般是用于需要显式的定义数据类型或者初始值不重要的地方。**
简短变量定义也支持组定义:
x, y := 10,20
简短变量的声明中必须有一个新的变量:
x,y := 10,20
x,y := 10,30
这种赋值方式是错误的,必须有新的变量的引入:
x,y := 10,20
z,y := 10,30
这样的话就是想当于第二次声明了一个新的变量z,并且对已经声明的y进行了赋值。
### 指针 ###
Go语言的指针和C语言的操作基本是没什么不同的,但Go语言的一个指针有一个很大的变动就是***函数可以返回局部变量的地址***。
Go语言的局部变量返回:
func f() *int{
a := 3
return &a
}
var p = f()
C语言的局部变量的返回:
int* func()
{
int a =1000000;
return &a;
}
int *sss = func();
对于C语言的写法编译的时候就会有warning,然后打印SSS和p的值,会发现go语言是一直保留局部变量的地址的值得,但C语言中,内存里的值就是不可预测的。
### new 函数
还有一个创建变量的方法是调用内建的new 函数,返回的是T类型的指针。定义模型为:
x := new(T)
eg:
p := new(int)
fmt.Println(*p)
*p = 2
fmt.Println(*p)
上述的例子创建了p指针,并且返回了p的值0,然后对*p的值进行赋值,最后输出2.
###变量的生命周期
对于Go语言的变量的生命周期,全局变量和程序的生命周期是一样的,但局部变量的周期是动态的:从每次创建变量,直到变量不再被引用为止,变量的存储空间才会被回收。这个就是前面的指针讲的代码,直到没有引用才会去回收内存。
case1:
var globle *int
func test1(){
x := 1
globle = &x
}
case2:
func test2(){
y := 2
*y = 3
}
func main(){
test1()
test2()
}
对于上述的例子x 内存因为被globle引用所以生存周期是伴随整个代码的,但y的内存是在test2结束之后就会自动释放。
***
##赋值操作
赋值操作基本和C语言没啥区别,有个元组赋值比较新颖,比如你要交换两个数值的值,用C语言的写法
int x = 10;
int y = 20;
int m = 0;
m = x;
x = y;
y = m;
对于GO:
x,y = y,x
这个特性和函数的多返回值还是很有关系的。
func f() (*int, *int) {
v := 2
a := 10
return &v, &a
}
p, q := f()
***
##包
包是GO语言里面很重要的一个概念,它和其它语言的库概念累死,主要为实现模块化,封装,单独编译,代码重用。通常包的名字和包的路径的最后一层目录名字是一样的
eg:
目录名 /src/test/hello/
包名 hello
<font size=6 color = red > 当你想把变量暴露给包外面的时候,只需要将首字母大写即可,反之则小写</font>
<font size=6 color = red >需要注意的是当你Import 引入一个包的时候,这个包是必须被使用的,如果不被使用,在编译期间就会报错</font>
当然你可以使用内置goimports工具,该工具可以自动去除掉未用到的包和添加用到的包。尝试过多种官方的安装方式,但貌似都有问题,下面这个网址可以安装。
有疑问加站长微信联系(非本文作者))