Go语言的程序元素
Go语言包含了五种程序符号,分别是标识符(identifier)、关键字(keyword)、运算符(operator)、分隔符(delimiter)与字面量(literal)。这五种程序元素组合成各种表达式和语句。
- 标识符
标识符是用于标识变量、函数或任何用户自定义项目的名称(程序实体)
标识符可分为两类,一类是用户定义的标识符,作为程序实体存在;另一类是预定义标识符,它们在Go语言中的源代码被声明(如数据类型)。
还有一个特殊的标识符,叫空标识符,记作 "_",一般用在变量声明与包的导入中。例如,在Go语言程序中,若存在一个没有使用的变量a,那么编译时就会报错,因为Go语言要求存在的程序实体必须被使用,这时就可以使用这样一句 _=a 的代码,编译器就会认为已经使用了变量a(实际上并没有使用),也就不会报错。
在大型的Go语言开发项目中,空标识符的运用很普遍,提高了代码的灵活性和可读性。
-
关键字
Go语言作为一门静态强类型的编译语言,它的关键字一共只有25个(均为小写)分别是:
- 包导入与声明:import、package
- 程序实体声明与定义:var、type、func、interface、map、struct、chan、const
- 流程控制:if、continute、for、return、go、case、goto、switch、select、else、break、default、defer、fallthrough、range
- 字面量
字面量是表示值的一种标记法(其实我觉得这个概念生涩难懂)举个例子很容易就理解是什么了。
var str string = "dog" //str为变量,dog为字面量
const b := 10 //b为变量,10为字面量
分隔符
//fmt.Println("b")使用括号和标点符分隔而成,包含了6个标记
fmt
.
Println
(
"b"
)
程序代码都是通过语句来实现结构化的,但**Go语言的语句结束不需要开发者手动写上分号,编译器会在每一行语句的末尾加上分号,这一过程是自动完成的**。
- 运算符
运算符是用于执行运算或逻辑操作的符号,**Go语言不支持运算符重载**。
在Go语言中,一元运算符的优先级高于二元运算符;如果一个表达式中出现相同优先级的运算符,就根据**从左到右的顺序依次操作**。
需要特别注意的是,在Go语言中,**++和- -是语句,不是表达式,没有运算符优先级一说**。
- 注释
Go语言的注释风格和C语言一样,分为单行注释和多行注释
/*
- 测试:使用http包实现服务
- 启动:bee run
- 访问: curl "http://127.0.0.1:8888/v1/demo"
*/
func main() {
// 初始化一个http.Server
server := &http.Server{}
// 初始化handler并赋值给server.Handler
server.Handler = DemoHandle{}
// 绑定地址
server.Addr = ":8888"
// 启动一个http服务
server.ListenAndServe()
}
## 常量
在Go语言中,常量是编译期间已知,且在执行过程中不会改变的固定值;在Go语言程序中,常量使用 const 关键字定义
//指定常量
const H = 1.287456875623903
//指定常量的类型,float64类型默认保留小数点后15位
const H float64 = 1.28745687562390300000
//bool值
const Return := true
//甚至可以使用中文
const 完满主任 = 100
- 数字表示
Go语言的常量可以是十进制、八进制或十六进制常数
1. 前缀0x或0X的是十六进制
2. 前缀0的是八进制
3. 十进制没有前缀
4. 整数可以有一个后缀,是字母U和L的组合,分别用于表示unsigned和long;后缀字母大小写和顺序都是任意的,但不能重复。
0123 //八进制,合法
0x3a //十六进制,合法
0xFeeL //合法
30l //long,合法
40u //无符号整型,合法
078 //后缀8不是八进制的数,非法
032UU //后缀不能重复,非法
## 转义字符
与其他程序语言一样,Go语言使用反斜杠 " \"表示转义符号,例如换行符 " \n"或制表符 " \t"
func main() {
fmt.Println("Hello\nGo") //换行
fmt.Println("Hello\tGo") //水平
}
以上程序实体的输出结果为:
$ Hello
$ Go
$ Hello Go
## 赋值
func main() {
a := 20
c := 200
c = a
//以下c的值依次被使用
fmt.Println("赋值操作,把a的值赋给c,c的值为:", c) //20
c += a
fmt.Println("相加和赋值运算符,c的值为:", c) //40
c -= a
fmt.Println("相减和赋值运算符,c的值为:", c) //20
c /= a
fmt.Println("相除和赋值运算符,c的值为:", c) //1
c *= a
fmt.Println("相乘和赋值运算符,c的值为:", c) //20
c <<= 2
fmt.Println("左移和赋值运算符,c的值为:", c) //80,正数左移1位相当于乘2 (左边的二进制丢弃,右边补0)
c >>= 2
fmt.Println("右移和赋值运算符,c的值为", c) //40,正数右移1位相当于除2 (正数左补0,负数左补1)
c &= 2
fmt.Println("按位与赋值运算符,c的值为:", c) //0
c ^= 2
fmt.Println("按位异或运算符,c的值为:", c) //2
c |= 2
fmt.Println("按位或和赋值运算符,c的值为:", c) //2
}
Go语言也支持并行赋值的写法:
func main() {
//使用并行赋值的方法
const (
a, b, c int = 1, 2, 3
d, e, f int = 4, 5, 6
)
//打印常量a,b,c,d,e,f的值
fmt.Println("分别是:", a, b, c, d, e, f)
}
## 枚举
在C/C++,Java等高级语言中,常常会用到枚举类型表示状态;在Go语言中却没有枚举类型,iota是Go语言的常量计数器,只能在常量的表达式中使用,因此可以借助iota实现枚举。
const (
a = iota //使用iota关键字实现枚举,每次const出现时,都会让iota的值初始化为0
b //b = 1
c //c = 2
d, e, f = iota, iota, iota //d, e, f = 3, 3, 3
g = iota // g = 4
h = "h" // h = "h"
i // i = 6
j = iota // j = 7
)
const z = iota // iota初始化为0,因此 z = 0
func main() {
//分别打印:0 1 2 3 3 3 4 h h 7 0
fmt.Println(a, b, c, d, e, f, g, h, i, j, z)
}
## 变量
- 声明变量的标准形式
//定义一个变量a为int型
var a int
//定义一个变量b为bool型
var b bool
//并行定义类型
var (
a, b int
c bool
str string
)
- 局部变量声明
声明变量有两种写法,一种是像上面使用 = ,另一种是使用赋值运算符号 := 代替。
a := 1 //等价于 a = 1,此处可以省略声明类型,因为编译器会自动推导
Go语言官方推荐使用这种方式声明变量,但有一点必须要注意,**这种声明方式只能被用于函数体内,不可以用于全局变量的声明与赋值。**
- 匿名变量
全局变量自然是全局可用,局部变量只能在相应代码块内使用,除此之外,局部变量还有一个特点就是,定义了后必须要使用(全局变量允许声明但可以不使用)否则编译器会报错。
但在使用强类型编程语言时,经常会在调用函数时,返回多个值,有时候我们只需要其中的一个值,不需要其他的值,就可以使用匿名变量来解决这个问题。匿名变量可以通过使用空标识符 "_" 来实现。
func GetClass() (ageNum int, stuTeacher string, isGirl bool) { //获取班级信息
return 78, "完满主任", false //多个返回值
}
func main() {
_, stuTeacher, _ := GetClass() //选取完满主任的名字,其他信息使用匿名变量屏蔽
fmt.Println(stuTeacher) //打印
}
- init函数初始化
在Go语言中,除了可以在全局声明中初始化实体,还可以借助init函数初始化,这个函数比较特殊,**它会在包完成初始化后自动执行,执行优先级比main函数更高,并且不能手动调用init函数。**每一个源代码文件有且只有一个init函数,初始化过程会根据包的依赖关系按**顺序单线程执行**。
有疑问加站长微信联系(非本文作者)