一、标识符
标识符是指定义的具有特殊意义的词,例如变量、常量、函数名等等,任何一门语言中都对自己的标识符有特殊定义的规则。在 Go 语言中,标识符由字母数字和下划线组成,并且只能以字母和下划线开头,例如:
-
数字、字母和下划线组成:
123
、abc _
-
只能以字母和下划线开头:
abc123
、_sysVar
、123abc
-
标识符区分大小写:
name
、Name
、NAME
二、关键字和保留字
关键字和保留字是指编程语言中预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名,会引起混乱和冲突。
1. GO中的关键字
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
2. GO中的保留字
Constants: true false iota nil ? Types: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex128 complex64 bool byte rune string error ? Functions: make len cap new append copy close delete complex real imag panic recover
三、命名规范
由于Go语言是一门区分大小写的语言,因此Go从语法层面进行了以下限定:任何需要对外暴露的名字必须以大写字母开头,不需要对外暴露的则应该以小写字母开头。
当命名(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:GetUserName
,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(程序需要先导入这个包),这被称为导出(类似面向对象语言中的公共属性); 命名如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(类似面向对象语言中的私有属性 )。
Go语言中各类情形的建议命名规则如下:
-
变量命名
变量名称一般遵循驼峰法,首字母根据访问控制原则大写或者小写
1 var userName string 2 var isExist bool
-
常量命名
常量均需使用全部大写字母组成,并使用下划线分词
const SITE_URL = "http://www.chendacheng.com"
-
结构体命名
采用驼峰命名法,首字母根据访问控制大写或者小写
1 type UserInfo struct { 2 Name string, 3 age int, 4 }
-
接口命名
命名规则基本和上面的结构体类型,单个函数的结构名以er
作为后缀
1 type Reader interface { 2 Read(p []byte) (n int, err error) 3 }
-
错误处理
错误处理的原则就是不能丢弃任何有返回err
的调用,不要使用_
丢弃,必须全部处理。接收到错误,要么返回err
,或者使用log
记录下来尽早return
。一旦有错误发生,马上返回,尽量不要使用panic
,除非你知道你在做什么,错误描述如果是英文必须为小写,不需要标点结尾,采用独立的错误流进行处理。
1 if err != nil { 2 // 错误处理 3 return // 或者继续 4 } 5 // 正常代码
-
包命名
尽量保持和目录保持一致,采取有意义的包名,简短且不要和标准库不要冲突。包名应该为小写单词,不要使用下划线或者混合大小写。
1 package dao 2 package service 3 package main
-
文件命名
尽量采取简短且有意义的文件名,应该为小写单词,使用下划线分隔各个单词。
1 customer_dao.go 2 user_manage.go
-
单元测试
单元测试文件名要以 _test.go
结尾,测试文件中的测试用例的函数名称必须以 Test
开头。
四、变量
变量的作用是存储数据,不同的变量保存的数据类型可能会不一样。Go 语言中的每一个变量都有自己的类型,变量必须经过声明才能开始使用,且同一作用域内不支持重复声明。
1. 变量的作用域
1.1 全局变量和局部变量
变量可以定义在函数内部(函数外的每个语句都必须以关键字开始,如:var
、const
、func
等),也可以定义在函数内部。定义在函数外部的变量称为 全局变量
,定义在函数内部的变量称为 局部变量
。在 GO 语言中,定义的局部变量必须使用,否则编译代码的时候将不被通过,定义的全局变量可以不使用。
1 package main 2 ? 3 var name string = "cdc" // 定义一个全局变量 4 ? 5 func main() { 6 ? 7 }
直接编译通过:
1 package main 2 ? 3 func main() { 4 name := "cdc" // 声明并初始化了一个局部变量,但是未使用 5 }
直接编译未通过,报错:
1.2 作用域
-
函数内可以使用全局的变量,但是在全局无法使用局部的变量
1 var name = "cdc" 2 ? 3 func main() { 4 fmt.Printf("%v\n", name) // cdc 5 } 6 func demo() { 7 var name = "cdc" 8 } 9 ? 10 func main() { 11 fmt.Printf("%v\n", name) // undefined: namet 12 ? 13 }
-
代码执行时,先从函数内部寻找局部变量,找不到再去找全局的变量
1 package main 2 ? 3 import "fmt" 4 ? 5 var name = "cdc" 6 var age = 22 7 ? 8 func main() { 9 ? 10 var name = "ctt" 11 12 ? 13 fmt.Printf("%v\n", name) // ctt 14 fmt.Printf("%v\n", age) // 22 15 }
2. 变量的声明
2.1 标准声明方式
变量声明以关键字 var
开头,变量类型放在变量的后面,行尾无需分号。
1 var name string 2 var age int 3 var isOk bool
2.2 批量声明
1 var ( 2 a string 3 b int 4 c bool 5 d float32 6 )
注意:在没有初始化变量之前,不同数据类型的变量会有一个默认值,值为该数据类型对应的0值:
1 package main 2 ? 3 import "fmt" 4 ? 5 func main() { 6 var ( 7 a string 8 b int 9 c bool 10 d float32 11 ) 12 ? 13 fmt.Println(a) // "" 14 fmt.Println(b) // 0 15 fmt.Println(c) // false 16 fmt.Println(d) // 0 1