命名

Go语言中的函数名变量名常量名类型名语句标号包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母数字下划线.大写字母和小写字母是不同的:heapSort和Heapsort是两个不同的名字.

Go语言的关键字有25个,关键字不能用于自定义名字. 分别为:

1
2
3
4
5
break      default       func     interface   select
case       defer         go       map         struct
chan       else          goto     package     switch
const      fallthrough   if       range       type
continue   for           import   return      var

还有大约30多个预定义的名字,这些内部预先定义的名字并不是关键字,你可以在定义中重新使用它们。在一些特殊的场景中重新定义它们也是有意义的,但是也要注意避免过度而引起语义混乱.

1
2
3
4
5
6
7
8
内建常量: true false iota nil
内建类型: int int8 int16 int32 int64
          uint uint8 uint16 uint32 uint64 uintptr
          float32 float64 complex128 complex64
          bool byte rune string error
内建函数: make len cap new append copy close delete
          complex real imag
          panic recover

在习惯上,Go语言程序员推荐使用 驼峰式 命名,当名字有几个单词组成的时优先使用大小写分隔,而不是优先用下划线分隔。

声明

Go语言主要有四种类型的声明语句:varconsttypefunc,分别对应变量常量类型函数实体对象的声明。

一个Go语言编写的程序对应一个或多个以.go为文件后缀名的源文件中。每个源文件以包的声明语句开始,说明该源文件是属于哪个包。包声明语句之后是import语句导入依赖的其它包,然后是包一级的类型、变量、常量、函数的声明语句.

1
2
3
4
5
6
7
8
9
package main // main包
import "fmt" // 引入fmt内部包
const price = 212.0 // 浮点型常量
func main() {
	var f = price                        // f浮点型变量
	var c = (f - 32) * 5 / 9             // c浮点型变量
	fmt.Printf("f = %g  c = %g\n", f, c) // %g为浮点型占位符
	fmt.Printf("f:%T,c:%T", f, c)        // %T为打印类型  结果:f:float64,c:float64
}

变量

var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。变量声明的一般语法如下:

var 变量名字 类型 = 表达式

1
2
// 例如
var name string = "zhy"

其中“类型”或“= 表达式”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量。 数值类型变量对应的零值是0,布尔类型变量对应的零值是false,字符串类型对应的零值是空字符串,接口或引用类型(包括slice、指针、map、chan和函数)变量对应的零值是nil。数组或结构体等聚合类型对应的零值是每个元素或字段都是对应该类型的零值。

1
2
var s string
fmt.Println(s) // ""

也可以在一个声明语句中同时声明一组变量,或用一组初始化表达式声明并初始化一组变量。如果省略每个变量的类型,将可以声明多个类型不同的变量(类型由初始化表达式推导):

1
2
var i, j, k int                 // int, int, int
var b, f, s = true, 2.3, "four" // bool, float64, string

一组变量也可以通过调用一个函数,由函数返回的多个返回值初始化:

1
var f, err = os.Open("./project.log")  // 打开文件 f为句柄 err为错误

简短变量声明

在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量,变量的类型根据表达式来自动推导。

1
2
name := "zhy"
f,err := os.Open("./project.log")

指针

一个变量对应一个保存了变量对应类型值的内存空间一个指针的值是另一个变量的地址。一个指针对应变量在内存中的存储位置。并不是每一个值都会有一个内存地址,但是对于每一个变量必然有对应的内存地址。通过指针,我们可以直接读或更新对应变量的值,而不需要知道该变量的名字(如果变量有名字的话)。指针的定义为*+类型比如*int等,或者把变量的地址赋值给指针,编辑器会自动推到指针的类型

1
2
3
var number *int
var a = 100
var b = &a // &为取值符

用*+指针变量出去所指变量的值

1
2
fmt.Println(*p)  // 0
fmt.Println(*b)  // 100

New初始化

另一个创建变量的方法是调用用内建的new函数。表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T。

1
2
3
4
p := new(int)   // p, *int 类型, 指向匿名的 int 变量
fmt.Println(*p) // "0"
*p = 2          // 设置 int 匿名变量的值为 2
fmt.Println(*p) // "2"

变量的生命周期

变量的生命周期指的是在程序运行期间变量有效存在的时间间隔。对于在包一级声明的变量来说,它们的生命周期和整个程序的运行周期是一致的。而相比之下,局部变量的声明周期则是动态的:**每次从创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。**函数的参数变量和返回值变量都是局部变量。它们在函数每次被调用的时候创建。

赋值

  • 直接赋值x = 100
  • 通过指针赋值*p = “zhy”
  • 结构体赋值stu.name = “zhy”
  • 数组切片赋值lst[1] = lst[1] + 1
  • 二元运算符x *= 6等同于x = x * 6
  • 自加自减x++x–
  • 交换赋值x,y = y,x
  • 函数赋值f, err = os.Open(“project.log”)

类型

一个类型声明语句创建了一个新的类型名称,和现有类型具有相同的底层结构。新命名的类型提供了一个方法,用来分隔不同概念的类型,这样即使它们底层类型相同也是不兼容的。

1
type 类型名字 底层类型

Go语言中的包和其他语言的库或模块的概念类似,目的都是为了支持模块化、封装、单独编译和代码重用。一个包的源代码保存在一个或多个以.go为文件后缀名的源文件中,通常一个包所在目录路径的后缀是包的导入路径;

作用域

一个声明语句将程序中的实体和一个名字关联,比如一个函数或一个变量。声明语句的作用域是指源代码中可以有效使用这个名字的范围

1
2
3
4
5
6
7
8
func f() {}
var g = "g"
func main() {
    f := "f"
    fmt.Println(f) // main函数的作用域
    fmt.Println(g) // g包作用域
    fmt.Println(h) // pinic报错 没有找到
}

用:=声明变量,只能在函数内使用,在全局使用会报错