顺序编程

1 变量

变量相当于是对一块数据存储空间的命名,程序通过定义一个变量来申请一块数据存储空间,之后通过引用变量名来使用这块存储空间

1.1 变量声明

Go语言引入关键字var来声明变量,类型放置在变量名后面

var v1 int
var v2 string
var v3 [10] int  //数组
var v4 [] int    //数组切片
var v5 struct {
	f int
}
var v6 *int      //指针
var v7 map[string] int     //map,key为string ,value为int
var v8 func(a int) int

//var关键字可以将若个要声明的变量放在一起,免得程序重复写var关键字,如:

var (
	v1 int
	v2 string
)

1.2 变量初始化

对于声明变量时需要初始化的场景下,var关键字可以保留,但是不是必要的元素了

var v1 int = 10 //方式1,常规方法
var v2 = 10 //方式2,编译器会自动推导出v2的类型
v3 := 10 //方式3,编译器会自动推导出v3的类型,:= 左侧的变量不应该是已经被声明过的,否则会编译报错

//如下面会导致编译报错:no new variables on left side of :=
var a int
a := 2

:= 用于明确表达式同时进行变量声明初始化的工作

1.3 变量赋值

Go语法中,变量初始化和变量赋值是两个不同的概念

// 下面为声明一个变量之后的赋值过程
var v10 int
v10 = 123
//下面为交换变量的语句
i, j = j, i

1.4 匿名变量

如函数返回了多个值,我们不想要其中的值时

_, _, nickName := GetName()

_ 表示忽略值,不会分配内存


2 常量

常量是指编译期间就已知且不可改变的值,常量可以是整型、浮点型、复数类型、布尔类型、字符串类型等

2.1 字面常量

常量,即为程序中硬编码的常量

-12 //整型常量
3.14159 //浮点型常量
3.12+12i //复数类型常量
true //布尔类型常量
"name" //字符串常量

2.2 常量定义

通过const关键字,可以给字面常量指定一个友好的名字

const Pi float64 = 3.14159265358
const zero = 0.0 //无类型浮点常量
const (
	size int64 = 1024
	eof = -1  //无类型整数常量
)
const u, v float32 = 0, 3 //常量的多重赋值
const a, b, c = 3, 4, "foo" // 无类型整型和字符串常量

常量定义可以是限定类型的,但不是必须的,如定义常量时没指定类型,那么它与字面常量一样,是无类型常量
常量的右值也可以是一个在编译期运算的常量表达式,比如

const mask = 1 << 3

但常量的赋值是一个编译期的行为,所以右值不能出现任何需要运行期才能得出结果的表达式,比如

const  Home = os.GetEnv("HOME")

因为 os.GetEnv("HOME")只有在运行期间才知道返回的结果,在编译期不能确定,所以无法作为常量定义的右值

2.3 预定义常量

Go语言预定义了这些常量:true、false、iota
iota 比较特殊,可以当成是一个被编译期修改的常量,在每一个const关键字出现时被重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字就会自动增1

const (           //iota被重设为0
	c0 = iota // c0 == 0
	c1 = iota // c1 == 1
	c2 = iota // c2 == 2
)

const(
	a = 1 << iota // a == 1, (iota在每个const开头被重设为0)  「0000 0001 像左移0位」
	b = 1 << iota // b == 2, (iota=1)「0000 0001 向左移1位变为 0000 0010」
	c = 1 << iota // c == 4, (iota=2)「0000 0001 向左移2位变为 0000 0100」
)

const (
	u         = iota * 42 // u == 42
	v float64 = iota * 42 // v == 42.0
	w         = iota * 42 //w == 84
)

如果两个const赋值语句表达式一样,可以省略写法

const (           //iota被重设为0
	c0 = iota // c0 == 0
	c1        // c1 == 1
	c2        // c2 == 2
)

const (
	a = 1 << iota // a == 1, (iota在每个const开头被重设为0)  「0000 0001 像左移0位」
	b             // b == 2, (iota=1)「0000 0001 向左移1位变为 0000 0010」
	c             // c == 4, (iota=2)「0000 0001 向左移2位变为 0000 0100」
)

2.4 枚举

枚举是指一系列相关的常量,比如一个星期中每天的定义

const (
	Sundat = iota
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Satirdau
	Saturday
	numberOfDays  // 此常量没有导出
)
// 以大写字母开头的常量在包外可见,numberOfDays为包内私有,其他常量则可以被其他包访问

3 类型

Go语言中内置了以下基础类型

  • 布尔类型:bool
  • 整型:int8、byte、int16、int、unit、unitptr
  • 浮点类型:float32、float64
  • 复数类型:complex64、complex128
  • 字符串:string
  • 字符类型:rune
  • 错误类型:error

和以下复合类型

  • 指针:pointer
  • 数组:array
  • 数组切片:slice
  • 字典:map
  • 通道:chan
  • 结构体:strut
  • 接口:interface

3.1 布尔类型

Go语言中的布尔类型与其他语言一致,关键字也为bool,可赋予的值为 true和false

var v1 bool
v1 = true
v2 := (1 == 2) // v2也会被推导为bool类型

布尔类型不接受其他类型的赋值,不支持自动或强制的类型转换,以下是错误用法

var b bool
b = 1 // 编译报错

以下的用法才是正确的

var b bool
b = (1 != 0) //编译正确,b==true

3.2 整型

整型是所有编程语言中最基础的数据类型,Go支持下列这些整型类型

  • int8 范围:-128 ~ 127
  • unit8(即byte) 范围:0 ~ 255
  • int16 范围:-32768 ~ 32767
  • unit16 范围:0 ~ 65535
  • int32 范围:-2 147 483 648 ~ 2 147 483 647
  • unit32 范围:0 ~4 294 967 295
  • int64 范围:-9 233 372 036 854 775 808 ~ 9 233 372 036 854 775 807
  • unit64 范围:0 ~ 18 446 744 073 709 551 615
  • int 范围:与平台相关
  • unit 范围:与平台相关
  • unitptr 范围:32位平台下为4字节,64位平台下为8字节

3.2.1 类型表示

需要注意的是int和int32在Go语言中被认为是两种不同的类型,编译器不会帮你自动做类型转换,下列情况会编译报错

var value2 int32
value1 := 64  //value1将会被自动推导为int类型
value2 = value1 //编译报错
// 报错信息:cannot user value1 (type int) as type int32 in assignment

使用强制类型转换可以解决这个编译报错

value2 = int32(value1)  // 编译通过

3.2.2 数值运算

Go语言支持常规运算:+,-,*,/ 和 % ,就不解释了,需要说明下 %表示取余

5 % 3 // 结果为 2

3.2.3 比较运算

Go语言支持的比较运算符:>, <, == , >=, <= 和 != 基本与其他语言一致,就不解释了,需要说明下的是,Go语言的两个不同类型的整型数是不能直接比较的,比如int8类型的数不能和int类型的数直接比较,但各种类型下的整型变量可以与字面常量进行比较,比如

var i int32
var j int64
i, j = 1, 2
if i == j {  // 编译报错
	...
}
if i == 1 || j == 2 {  // 编译通过
	...
}

3.2.4 位运算

124 << 2  // 496, 124的二进制向左移2位
124 >> 2  // 31, 124的二进制向右移2位
124 ^ 2   // 126, 异或,相同为1,不同为0
124 & 2   // 0, 与,都为1时为1,否则为0
124 | 2   //126, 或,只要有一个1就为1,否则为0
^2        // -3, 取反,标识位也取反 010 -> 101, 101 -> -101 ,故为-3

3.3 浮点类型

浮点型表示包含小数点的数据,Go语言中浮点类型采用的是IEEE-754标准的表达方式

3.3.1 浮点数表示

var fvalue1 float32
fvalue1 = 12
fvalue2 := 12.0 //如果不加小数点,fvalue2会被推导为整型,该浮点变量将被自动转为float64

fvalue1 = fvalue2  //将会报错,需要进行下列强制转换
fvalue1 = float32(fvalue2)

3.3.1 浮点数比较

因浮点数不是一种精确的表达方式,直接用 == 来判断是不可行的,可能导致不稳定的结果,下面是替代方案

import "math"
func IsEqual(f1, f2, p float64) bool {
	retrun math.Abs(f1-f2) < p
}

3.4 复数类型

复数实际上是由两个实数(计算机中用浮点数表示)构成,一个表示实部(real),一个表示虚部(image)

3.4.1 复数表示

var value1 complex64      //由2个float32构成的复数类型
value1 = 3.2 + 12i
value2 := 3.2 + 12i       // value2 是complex128类型
value3 = complex(3.2, 12) // value3结果同 value

3.4.2 实部与虚部

z = complex(x, y) //复数 
x = reala(z)      // 通过内置函数获取实部x
y = imag(z)       // 通过内置函数获取虚部y

3.5 字符串

Go语言中字符串的声明和初始化非常简单

var str string         // 声明一个字符串变量
str = "Hello Word"     // 字符串赋值
ch := str[0]           // 获取字符串的第一个字符

字符串可以类似于数组,通过下标获取内容,但字符串的内容不可以在初始化之后被修改,如下会编译报错

str := "Hello Word"
str[0] = h  // 编译报错:cannot assigin to str[0]

3.5.1 字符串操作

"hello" + "word"  // 结果为 helloword,字符拼接
len(hello)        //结果为5,获取字符串长度
"hello"[1]        //结果为e,获取字符

3.5.2 字符串遍历

Go语言支持两种方式遍历字符串
一种是以字节数组的方式遍历

str := "Hello, 世界"
n := len(str)
for i := 0; i < n; i++ {
	ch := str[i]  //根据下标取字符串的字符,ch类型为byte
	fmt.Println(i, ch)
}

输出结果:
0 72
1 101
2 108
3 108
4 111
5 44
6 32
7 228
8 184
9 150
10 231
11 149
12 140
// 字符长度实际是13,因每个中文占3个字节,而不是1个字节

另一种是以Unicode字符遍历

str := "Hello, 世界"
for i,ch := range str {
	fmt.Println(i, ch)  //ch的类型为rune
}

输出结果:
0 72
1 101
2 108
3 108
4 111
5 44
6 32
7 19990
10 30028
// 以Unicode字符方式遍历时,每个字符的类型是rune

3.6 字符类型

Go语言中支持两个字符串的类型
一个是byte(实际是unit8的别名),代表UTF-8字符串的单个字节的值,另一个是rune,代表单个Unicode字符
标准库unicode包中提供了UTF8和Unicode之间的转换
Go语言多少API都假设字符串为UTF-8编码,尽管Unicode字符在标准库中有支持,但实际上较少使用。

3.7 数组

数组是Go语言编程中最常用的数据结构之一,数组长度在定义后就不可更改
声明方法

[32]byte                   // 长度为32的数组,每个元素为一个字节
[2*N] struct {x, y int32}  //复杂类型数组
[1000]*float64    // 指针数组
[3][5] int         // 二维数组,表示3行5列的二维数组
[2][2][2] float64 // 等同于 [2]([2]([2]float64))

3.7.1 元素访问

for i := 0; i < len(array); i++ {
	fmt.Println(array[i])
}

for i, v := rang array {  // i表示下标,v表示值
	fmt.Println(v)
}

3.7.2 值类型

在Go语言中数组是一个值类型 (value type)

3.8 数组切片

3.9 map


4 流程控制


5 函数


6 错误处理


7 完整示例

posted @ 2022-04-16 14:17  大切切  阅读(32)  评论(0编辑  收藏  举报