Q1ngying

今朝梦醒与君别,遥盼春风寄相思

0%

go语言入门-1

学校课程安排有 Go 语言,简单学一下 go。本篇文章主要是 Go 语言文件的基本架构,以及一些 go 语言中的关键字,标识符,变量、常量声明,iota、init、函数、匿名变量等。

Go 文件基本构成

首先,go 语言需要一个导入一个 package ,也就是说,每个go 文件都需要导入 package main ,同时,还必须有一个主函数。

go 语言声明函数使用 func 关键字, 使用 import 导入标准库

同时,go 语言换行不需要使用 ;

1
2
3
4
5
6
7
package main

import fmt

func main() {
fmt.Println("hello, world")
}

go 语言还支持直接将文件编译成二进制文件,便于文件的移植,可以在终端使用如下命令:

1
go build -o <name> <path> 

go 语法

标识符

  • 数据类型
    • bool、bytes、uint16、float32、float64、int、int8、int16、uint32、int64、uint64、string、uint、uint8、uintptr
  • 内建函数
    • append、cap、close、complex、copy、delete、imag、len、make、new、panic、print、println、real、recover
  • 其他标识符
    • iota、nil、_

关键字

  • 使用 package 定义包名
  • 使用import关键字导入包名
  • 使用const关键字定义常量
  • 使用var关键字定义变量
  • 使用func 关键字声明函数
  • return 用于函数返回
  • if else 用于条件逻辑
  • for change break continue for 循环
  • switch select type case default fallthrough switch 和 select 语句
  • interface 用于定义接口
  • struct 定义结构体
  • map 声明或创建 map 类型
  • chan 声明或创建管道类型
  • defer用于延迟执行
  • go 用于并发语句
  • goto 用于 goto 跳转语句

字面量

字面量包括以下几类:

  • 整型
  • 浮点型
  • 复数
  • 字符型
    • 字符型使用''(单引号)将字符包围
  • 字符串
    • 字符串使用""(双引号)包围

常量

常量的定义

  • 显式定义:
1
const a string = "apple"
  • 隐式定义:
1
const a = "apple"

go 语言的常量可以是十进制、八进制、十六进制、字符串

  1. 十进制无前缀
  2. 前缀为 0 的是八进制
  3. 前缀为 0x0X 的是十六进制
  4. 整数还可以有一个后缀,其后缀可以是大小写字母(任意顺序)。后缀通常是 UL 的组合,通常用于表示 unsignedlong。:
1
2
3
4
5
6
3.1415926 // 十进制,合法
0215 // 八进制,,合法
0x25 // 十六进制,合法
30u // 无符号整型,合法
25l // long,合法
25ul // 无符号,long,合法

常量的声明

常量和变量声明的区别只在关键字上。多个变量和多个常量都可以一同声明

go 语言中,常量的运算是在编译期完成的,可以减少运行时的工作,方便其他代码的编译优化,安全度更高。

常量间的所有算术运算、逻辑运算、比较运算的结果也是常量,对常量的类型转换操作或函数调用(len、cap、real、imag、complex、unsafe.Sizeof)都是返回常量结果

由于常量的值是在编译期就确定的,常量可以用于数组的声明

1
2
const size = 5
var arr [size] int

批量声明常量,除了第一个常量外,其他的常量右边的初始化表达式都可以省略

1
2
3
4
5
6
7
const (
a = 3
b
c = 5
d
)
fmt.Println(a, b, c, d) // "3 3 5 5 "

特殊常量 iota

Go 中有一个特殊常量——iota iota 是一个可以被编译器修改的常量

iotaconst 关键字出现时被重置为 0,const 中每新增一行常量声明则使 iota 计数加一。

1
2
3
4
5
6
const (
a = iota
b
c
)
fmt.Println(a, b, c) // 0 1 2
1
2
3
4
5
6
7
8
9
10
const (
a = iota
b
c
x = 3
d = iota
e
f
)
fmt.Println(a, b, c, d, e, f) // 0 1 2 4 5 6 7

注意,是 const 关键字出现时重置为 0,且 const 中,每新增一行 iota 实际代表的值就加 1,所以刚刚的 d 取值为 4,而不是 1

枚举

常量也可以用作枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const(
Connected = 0
Disconnected = 1
Unknow = 2
)
// 枚举类型的实现需要使用 iota 关键字
package main
import (

"fmt"
)

const (
a =iota // a ==0
b // b ==1 隐式使用 iota 关键字,等同于 b = iota
c // c ==2 饮食使用 iota 关键字,等同于 c = iota
d, e, f = iota, iota, iota // d = 3, e = 3, f = 3,同一行值相同
g =iota // g ==4
h = "h" // h == "h" 单独赋值,iota 递增到 5
i // i == "h" ,默认使用上面的赋值,递增到6
j = iota // j == 7
)
const z =iota // 每个单独定义的 const 常量中,iota 会重置,此时 z == 0
func main() {
fmt.Println(a, b, c, d, e, f, g, h, i ,j ,z)
}

运行结果:0 1 2 3 3 3 4 h h 7 0

每个 const 定义的第一个常量被默认设置为 0 ,显示设置为其他值除外。后续的常量默认设置为上面那个常量的值。如果前面的常量的值是 iota,那么他也会被设置为 iota。由于 iota 可以实现递增,因此它也可以实现枚举操作,并且 iota 可以在表达式中使用

注意:当遇到 d, e, f = iota, iota, iota 这种情况时,虽然同一行值相同,但不能省略其他 iota,需要书写完整

变量

变量的声明

变量声明有很多方法:

1
2
3
4
5
6
7
8
var c1 int
c1 = 10

var c2 int = 7

var c3 = 8

c4 := 5

go 语言中,变量声明后,没有被使用,程序会报错(Rust 也是)

同时注意,:= 算作变量的声明,而不是赋值,所以使用:=为一个已经定义过的变量赋值会报错,错误原因为重复定义,因为:=是用来声明变量的。赋值只需要使用=即可

使用 var 关键字进行声明时候,可以声明很多类型:

1
2
3
4
5
6
7
var a int               // 声明整型变量
var b string // 声明字符型变量
var c []float32 // 声明 32 位浮点切片类型变量,浮点切片有多个浮点类型组成的数据结构
var d func() bool // 声明返回值为 bool 类型的函数变量
var e struct { // 声明结构体类型变量
x int
}

同时,还有以下的便捷操作:

  • 类似于常量 const 可以使用 var() 一同声明多个变量
  • 同一类型多个变量可以在同一行声明
  • 多个变量可以在同一行进行声明和赋值
  • 想要交换两个变量的值,可以直接交换(类 Python )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 使用 `var()` 一同声明多个变量
var(
a int
b string
c []float32
d func() bool
e struct {
x int
}
)
// 同一类型多个变量可以在同一行声明
var a, b, c int
// 多个变量可以在同一行进行声明和赋值
var a, b, c int = 1, 2 ,3
// 想要交换两个变量的值,可以直接交换(类 Python )
a, b = b, a

init 函数

go 中,除了可以在全局变量中初始化实体,也可以在 init 函数中初始化。init 函数是一个特殊的函数,他会在包完成初始话后自动执行,执行优先级高于 main 函数,并且不能手动调用 init 函数,每个源文件只能有一个 init 函数。初始化过程会根据包的依赖关系按顺序单线程执行

可以在开始执行程序之前通过 init 函数来对数据进行检验与修复,保证程序执行时状态正常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"fmt"
"math"
)
// Pi 为圆周率
var Pi float64

func init() {
Pi = 4 *math.Atan(1) // 在 init 函数中计算 Pi 的值
}

func main() {
DPi := Pi
fmt.Println(Pi, DPi)
}

变量初始化

  1. 整型和浮点型变量默认值为 0
  2. 字符串变量默认值为空字符串
  3. 布尔型默认值为false
  4. 切片、函数、指针默认值为 null

匿名变量

go 支持使用 _ 作为匿名变量(Rust 好像有,Python 有)