Ezio's Blog
Posts Categories Tags Music Mood About
Ezio's Blog· Light
☰ Menu
Posts Categories Tags Music Mood About
Expand all Back to top Go to bottom

Go程序结构

Author: Ezio Date: February 24, 2021  9:47:57 Category: Go

  • GO语言学习资料推荐:Go语言圣经 《The Go Programming Language》中文翻译版 :http://books.studygolang.com/gopl-zh/

命名

名字必须以一个字母或下划线开头,后面可跟数字、字母、下划线。区分大小写

关键字:

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

**预定义名字:**主要对应内建常量、类型和函数

1
2
3
4
5
6
7
8
9
10
内建常量: 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语言主要有四种类型的声明语句:var、const、type 和 func,分别对应变量、常量、类型和函数实体对象的声明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//声明包
package main

//导入依赖
import "fmt"

//声明常量
const boilingF = 212.0

//声明函数
func main() {
//声明变量
var f = boilingF
var c = (f - 32) * 5 / 9
//按格式打印输出
fmt.Printf("boiling point = %g°F or %g°C\n", f, c)
// Output:
// boiling point = 212°F or 100°C
}

变量

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

1
var 变量名字 类型 = 表达式

其中 “类型 “ 或 “= 表达式” 两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量。

**零值初始化机制:**可以确保每个声明的变量总是有一个良好定义的值,因此在Go语言中不存在未初始化的变量。

  • 数值类型变量对应的零值:0

  • 布尔类型变量对应的零值:false

  • 字符串类型对应的零值:”“

  • 接口或引用类型(包括slice、指针、map、chan和函数)变量对应的零值:nil

  • 数组或结构体等聚合类型对应的零值:每个元素或字段都是对应该类型的零值。

多变量声明

可同时声明多个变量,如果省略每个变量的类型,将可以声明多个类型不同的变量(类型由初始化表达式推导):

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(name) // os.Open returns a file and an error

简短变量声明

1
变量名 := 表达式
1
2
3
anim := gif.GIF{LoopCount: nframes}
freq := rand.Float64() * 3.0
t := 0.0

和var形式声明语句一样,简短变量声明语句也可以用来声明和初始化一组变量:

1
i, j := 0, 1

注意区分: **” := “**是变量声明语句, **”=“**是变量赋值操作

将右边各个表达式的值赋值给左边对应位置的各个变量:

1
i, j = j, i // 交换 i 和 j 的值

但如果变量之前声明过,则再次使用:=声明则是赋值行为,其中err变量之前已经声明,则后面是对其进行赋值。且简短变量声明必须有一个新的变量被声明,否则编译不通过。

1
2
3
in, err := os.Open(infile)
// ...
out, err := os.Create(outfile)

指针

  • 一个变量对应一个保存了变量对应类型值的内存空间。

  • 一个指针的值是另一个变量的地址。

  • 一个指针对应变量在内存中的存储位置。

  • 并不是每一个值都会有一个内存地址,但是对于每一个变量必然有对应的内存地址。

  • 通过指针,我们可以直接读或更新对应变量的值,而不需要知道该变量的名字(如果变量有名字的话)。

如果用“var x int”声明语句声明一个x变量,那么&x表达式(取x变量的内存地址)将产生一个指向该整数变量的指针,指针对应的数据类型是*int,指针被称之为“指向int类型的指针”。如果指针名字为p,那么可以说“p指针指向变量x”,或者说“p指针保存了x变量的内存地址”。同时*p表达式对应p指针指向的变量的值。一般*p表达式读取指针指向的变量的值,这里为int类型的值,同时因为*p对应一个变量,所以该表达式也可以出现在赋值语句的左边,表示更新指针所指向的变量的值。

1
2
3
4
5
6
7
8
9
//声明变量
x := 1
//声明指向x变量的指针 p
p := &x // p, of type *int, points to x
//*p p指针指向的变量的值
fmt.Println(*p) // "1"
//更新指针所指向变量的值
*p = 2 // equivalent to x = 2
fmt.Println(x) // "2"

任何类型的指针的零值都是nil。如果p指向某个有效变量,那么p != nil测试为真。指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是nil时才相等。

1
2
var x, y int
fmt.Println(&x == &x, &x == &y, &x == nil) // "true false false"

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"

由于new只是一个预定义的函数,它并不是一个关键字,因此我们可以将new名字重新定义为别的类型。例如下面的例子:

1
func delta(old, new int) int { return new - old }

由于new被定义为int类型的变量名,因此在delta函数内部是无法使用内置的new函数的。

变量的声明周期

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


赋值

1
2
3
4
x = 1                       // 命名变量的赋值
*p = true // 通过指针间接赋值
person.name = "bob" // 结构体字段赋值
count[x] = count[x] * scale // 数组、slice或map的元素赋值

特定的二元算术运算符和赋值语句的复合操作有一个简洁形式,例如上面最后的语句可以重写为:

1
count[x] *= scale

数值变量也可以支持++递增和--递减语句(译注:自增和自减是语句,而不是表达式,因此x = i++之类的表达式是错误的):

1
2
3
v := 1
v++ // 等价方式 v = v + 1;v 变成 2
v-- // 等价方式 v = v - 1;v 变成 1

Author: Ezio

Permalink: https://ezioy.cn/2021/02/24/Go%E7%A8%8B%E5%BA%8F%E7%BB%93%E6%9E%84/

License: Copyright (c) 2019 CC-BY-NC-4.0 LICENSE

Slogan: Nothing is true,Everything is permitted

Tag(s): # Go
back · home
Quartz 定时任务 JVM运行时数据区
Ezio © 2019 - 2026 | Powered by Hexo & Chic | 访客数量:   浏览次数: | 渝公网安备50011302222043 | 渝ICP备2023013933号-1