第三章 Golang 变量
Golang 变量
为什么需要变量
- 变量是程序的基本组成单位。
- 不论是使用那种高级程序语言编写程序,变量都是其程序的基本组成单位。
变量的介绍
变量的概念
- 变量相当于内存中一个数据存储空间的表示,你可以把变量看作是一个房间的门牌号,通过门牌号我们可以找到房间,同样的道理,通过变量名可以访问到变量值。
变量使用的基本步骤
- 声明变量/定义变量
- 赋值
- 使用
变量快速入门案例
- 案例一:
1 | package main |
变量使用注意事项
变量表示内存中的一个存储区域。
该区域有自己的变量名和数据类型。
Golang 变量使用的三种方式。
第一种:指定变量类型,声明后若不赋值,使用默认值。
第二种:根据值自行判定变量类型(类型推导)。
第三种:省略 var ,注意 := 左侧变量不应该是已经声明的,否则会导致编译错误。
多变量声明:在编程中,又是我们需要一次性声明多个变量,Golang 也提供这样的语法。
该区域的数据值可以在同一类型范围内不断变化。
变量在同一个作用域内不能重名。
变量 = 变量名 + 值 + 数据类型。
Golang 的变量如果没有赋初始值,编译器会使用默认值,比如 int 默认值 0 ;string 默认值为空字符串。
Golang 变量使用的第一种方式
1 | package main |
- Golang 变量使用的第二种方式
1 | package main |
- Golang 变量使用的第三种方式
1 | package main |
- 多变量声明案例
1 | package main |
- 多变量声明案例(全局变量)
1 | package main |
- 该区域的数据值可以在同一类型范围内不断变化-相关案例
1 | package main |
- 变量在(同一个作用域或代码块)内不能重名-相关案例
1 | package main |
变量的声明,初始化和赋值
变量的基本语法
基本语法:var 变量名 数据类型
var a int 这就是声明了一个变量,变量名是 a 。
var num1 float32 这也声明了一个变量,表示一个单精度类型的小数,变量名是 num1 。
初始化变量
在声明变量的时候,就给值 。
var a int = 45 这就是初始化变量 a 。
使用细节:如果声明时就直接赋值,可省略数据类型。
1
var b = 400
给变量赋值
比如你先声明了变量: var num int // 默认 0
然后,再给值 num = 780 ;这就是给变量赋值。
程序中 + 号的使用
- 当左右两边都是数值型,则做加法运算。
- 当左右两边都是字符串,则做字符拼接。
1 | package main |
变量的数据类型
- 每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间。
- 数据类型中的基本数据类型包括:数值型、字符型(没有专门的字符型、使用 byte 来保存单个字母字符)、布尔型、字符串(官方将 string 归属到基本数据类型)。
- 数据类型中的派生/复杂数据类型:指针(Pointer)、数组、结构体(struct)、管道(Channel)、函数、切片(slice)、接口(interface)、map。
- 数值型变量包含:整数类型(int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, byte)、浮点类型:float32/float64 。
整数类型
基本介绍
- 简单来说,就是用来存放着整数值的,比如 0,-1,2345 等。
整数类型的详细介绍
类型 | 有无符号 | 占用存储空间 | 表数范围 | 备注 |
---|---|---|---|---|
int8 | 有 | 1 字节 | -128-127 | |
int16 | 有 | 2 字节 | -2^15~2^15-1 | |
int32 | 有 | 4 字节 | -2^31~2^31-1 | |
int64 | 有 | 8 字节 | -2^63~2^63-1 | |
uint8 | 无 | 1 字节 | 0~255 | |
uint16 | 无 | 2 字节 | 0~2^16-1 | |
uint32 | 无 | 2 字节 | 0~2^32-1 | |
uint64 | 无 | 2 字节 | 0~2^64-1 |
其他类型的详细介绍
类型 | 有无符号 | 占用存储空间 | 表数范围 | 备注 |
---|---|---|---|---|
int | 有 | 32 位系统 4 个字节 64 位系统 8 个字节 |
[-2^31-2^31-1, -2^63-2^63-1] | |
uint | 无 | 32 位系统 4 个字节 64 位系统 8 个字节 |
[0-2^32-1, 0-2^64-1] | |
rune | 有 | 与 int32 一样 | [-2^31, 2^31-1] | 等价 int32,表示一个 Unicode 码 |
byte | 无 | 与无符号的 uint8 等价 | [0, 255] | 当要存储字符时选用 byte |
案例演示
1 | package main |
整数类型的使用细节
- Golang 各整数类型分:有符号和无符号,int、uint 的大小和系统有关。
- Golang 的整型默认声明为 int 型。
1 | package main |
- 如何在程序中查看某个变量的占用字节大小和数据类型。
1 | package main |
- Golang 程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型。
1 | package main |
- bit:计算机中的最小存储单位。byte:计算机中基本存储单元。
浮点类型
基本介绍
- Golang 的浮点类型可以表示一个小数,比如 123.4,7.8,0.12 等等。
浮点型的分类
类型 | 占用存储 | 表数范围 |
---|---|---|
单精度 float32 | 4 个字节 | -3.403E38~3.403E38 |
双精度 float64 | 8 个字节 | -1.798E308~1.798E308 |
- 关于浮点数在机器中存放形式的简单说明,浮点数=符号数+指数位+尾数位。
1 | package main |
- 尾数部分可能丢失,造成精度损失。
1 | package main |
浮点型使用细节
Golang 浮点类型有固定的范围和字段长度,不受具体 OS(操作系统) 的影响。
Golang 的浮点型默认声明为 float64 类型。
浮点型常量有两种表示形式
十进制数形式: 如:5.12 .512(必须有小数点)
科学技术法形式: 如:5.1234e2 = 5.12 * 10 的两次方 5.12E-2 = 5.12、10 的 2 次方。
通常情况下,应该使用 float64 ,因为它比 float32 更准确。
浮点型使用细节的相关案例
1 | package main |
字符类型(char)
基本介绍
- Golang 中没有专门的字符类型,如果要储存单个字符(字母),一般使用 byte 来保存。
- 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而 Go 的字符串不同,它是由字节组成的。
相关案例
- 如果我们保存的字符在 ASCII 表的,比如 [0-1,a-z,A-Z] 直接可以保存到 byte 。
- 如果我保存的字符对应码值大于 255,这时我们可以考虑使用 int 类型保存。
- 如果我们需要按字符的方式输出,这时我们需要格式化输出,即 fmt.print(“%c”, c1) 。
1 | package main |
字符类型使用细节
- 字符常量是用单引号 ‘’ 括起来的单个字符。例如:var c1 byte = ‘a’ var c2 int = ‘中’ var c3 byte = ‘9’。
- Go 中允许使用转义字符来将其后的字符转变为特殊字符型常量。例如:var c3 char = ‘\n’ // ‘\n’ 表示换行符。
- Go 语言的字符使用 UTF-8 编码。(英文字母 1 个字节、汉字 3个字符)
- 在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
- 可以直接给某个变量赋一个数字,然后按格式化输出时 %c ,会输出该数字对应的 unicode 字符。
1 | package main |
- 字符类型是可以进行运算的,相当于一个整数,因为它都对应有 Unicode 码。
1 | package main |
字符类型本质探讨
给付型储存到计算机,需要将字符对应的码值(整数)找出来
存储:字符 –> 对应码值 –> 二进制 –> 存储
读取:二进制 –> 码值 –> 字符 –> 读取
字符和码值是通过字符编码表决定好的(是规定好)
Go 语言的编码都同意成了 utf-8 ,和其他的编程语言来说。非常的方便,很统一,再没有编码的困扰了。
布尔类型
基本介绍
布尔类型也叫 bool 类型,bool 类型数据只允许取值 true 和 false 。
bool 类型占一个字节。
bool 类型适于逻辑运算,一般用于程序流程控制。
if 条件控制语句
for 循环控制语句
相关案例
1 | package main |
字符串类型
基本介绍
- 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。
快速入门案例
1 | package main |
注意事项和使用细节
- Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本,这样 Golang 统一使用 UTF-8 编码,乱码的问题不会再困扰程序员。
- 字符串一旦赋值了,字符串就不能修改了:在 Go 中字符串是不可变的。
1 | package main |
字符串的两种表示形式
双引号,会识别转义字符
反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果。
1 | package main |
- 字符串的拼接方式
1 | package main |
- 当一行字符串太长,需要使用到多行字符串,可以如下处理:
1 | package main |
基本数据类型默认值
基本介绍
- 在 Go 中,数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值,在 Go 中,默认值又叫零值。
- 基本数据类型默认值如下:
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0 |
字符串 | “” |
布尔类型 | false |
- 相关案例
1 | package main |
基本数据类型的转换
基本介绍
- Golang 和 Java/C 不同,Go 在不同类型的变量之间赋值时需要显式转换。也就是说 Golang 中数据类型不能自动转换。
基本语法
表达式 T(v) 将值 v 转换为类型 T
T: 就是数据类型,比如 int32、int64、float32 等
v: 就是需要转换的变量
细节说明
- Go 中,数据类型的转换可以是从表示范围小–>表示范围大,也可以范围大–>范围小。
- 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化!
- 在转换中,比如将 int64 转换成 int8 ,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。
- 相关案例如下:
1 | package main |
基本数据类型和 string 的转换
基本介绍
- 在程序开发中,我们经常需要将基本数据类型转成 string 类型,或者将 string 类型转换成基本数据类型。
基本数据类型转 string 类型
方式1:fmt.Sprintf(“%参数”,表达式)
参数需要和表达式的数据类型相匹配
fmt.Sprintf() 会返回转换后的字符串
方式2:使用 strconv 包的函数
相关案例
方式一:
1 | package main |
方式二:
1 | package main |
string 类型转基本数据类型
- 使用 strconv 包的函数
1 | package main |
- 函数一般返回 int64 或者 float64 ,如果要获得 int32 或 float32 ,还需加一步转换。
注意事项
- 在将 String 类型转成基本数据类型时,要确保 String 类型能够转成有效的数据,比如我们可以把 “123”,转成一个整数,但是不能把 “hello” 转成一个整数,如果这样做,Golang 直接将其转成 0 。
1 | package main |
指针
基本介绍
- 基本数据类型,变量存的就是值,也叫值类型。
- 获取变量的地址,用 & ,比如: var num int,获取 num 的地址:&num
- 指针类型,变量存的是一个地址,这个地址指向的空间存的才是值。比如:var ptr *int = &num
- 获取指针类型指向的值,使用: *,比如: var ptr *int,使用 *ptr 获取 ptr 指向值。
- 相关案例
1 | //案例一 |
1 | //案例二 |
1 | //案例三 |
指针的细节说明
- 值类型,都有对应的指针类型,形式为 * 数据类型,比如 int 的对应的指针就是 *int,float32 对应的指针类型就是 *float32 ,依此类推。
- 值类型包括:基本数据类型 int 系列、float 系列、bool、string、数组和结构体 struct。
值类型和引用类型
常见的值类型和引用类型
- 值类型:基本数据类型 int 系列、float 系列、bool、string、数组和结构体 struct 。
- 引用类型:指针、slice 切片、map、管道 chan、interface 都是引用类型。
值类型和引用类型使用特点
- 值类型:变量直接存储值,内存通常在栈中分配。
- 引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由 GC 来回收。
标识符的命名规范
标识符概念
- Golang 对各种变量、方法、函数等命令时使用的字符序列称为标识符。
- 凡是自己可以起名字的地方都叫标识符。
标识符的命名规则
- 由 26 个英文字母大小写,0-9 ,_ 组成。
- 数字不可以开头。
- Golang 中严格区分大小写。
1 | package main |
- 标识符不能包含空格。
1 | package main |
- 下划线 _ 本身在 Go 中是一个特殊的标识符,称为空标识符。可以代表任何其他的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用。
1 | package main |
- 不能以系统保留关键字作为标识符,比如 break,if 等等…。
1 | package main |
标识符命名注意事项
- 包名:保持 package 的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库冲突。
- 变量名、函数名、常量名:采用驼峰法。
- 如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用(注:可以简单的理解成,首字母大写是公有的,首字母小写是私有的)
1 | //目录: /Users/mac/Desktop/GoProject/src/go_code/chapter03/variable_case_19/main/main.go |
保留关键字介绍
- 在 Go 中,为了简化代码编译过程中对代码的解析,其定义的保留关键字只有 25 个。
保留关键字 | 保留关键字 | 保留关键字 | 保留关键字 | 保留关键字 | 保留关键字 |
---|---|---|---|---|---|
break | default | func | interface | select | |
case | defer | go | map | struct | |
chan | else | goto | package | switch | |
const | fallthrought | if | range | type | |
continue | for | import | return | var |
预定义标识符介绍
- 除了保留关键字外,Go 还提供了 36 个预定的标识符,其中包括基础数据类型和系统内嵌函数。
预定义标识符 | 预定义标识符 | 预定义标识符 | 预定义标识符 | 预定义标识符 | 预定义标识符 |
---|---|---|---|---|---|
append | bool | byte | cap | close | complex |
complex64 | complex128 | unit16 | copy | false | float32 |
float64 | imag | int | int8 | int16 | int16 |
int32 | int64 | iota | len | make | new |
nil | panic | uint64 | println | real | |
recover | string | true | uint | uint8 | unitprt |
常量
常量介绍
- 常量使用 const 修改
- 常量在定义的时候,必须初始化
- 常量不能修改
- 常量只能修饰 bool、数值类型(int、float 系列)、string 类型
- 语法
1 | const identifier [type] = value |
- 举例说明
1 | package main |
常量的注意事项
- 比较简洁的写法
1 | const ( |
- 专业写法
1 | func main() { |
- Golang 中没有常量名必须字母大写的规范
- 仍然通过首字母的大小写来控制常量的访问范围