1、常量
1.1 常量简介
-
常量:常量一旦被赋值,在整个程序运行的生命周内,值都不允许被修改。
-
Go常量的来源:
- 字面量
- 其他常量标识符
- 常量表达式
- 结果是常量的类型转换
- iota
-
常量的类型只能是
基本类型,不能是除基本类型外的所有类型,如:结构体、切片、数组等,也不能是函数的返回值。
1.2 常量初始化
- 常量使用
const关键字声明,在声明时,常量必须初始化值。
const name = "zhangsan"
const num = 3
- 常量的批量声明
const (
Name = "zhangsan"
Num = 3
)
- 在同一组内的常量,如果常量值一样,除第一个常量外,剩余的不用赋值。
const (
A = 1
B //1
C //1
D //1
)
1.3 iota
iota是一个内置的常量标识符,通常用于表示一个常量声明中的无类型整数序数,一般都是在批量声明的括号中使用。
const (
A = iota //0
B //1
C //2
D //3
)
const (
A = iota * 2 //0
B //2
C //4
D //6
)
- 使用了匿名标识符
_占了一行的位置,可以看到iota的值本质上就是iota所在行相对于当前const分组的第一行的差值。而不同的const分组则相互不会影响。
const (
A = iota //0
B //1
C //2
_ //3
D //4
)
1.4 枚举
-
在Go中没有
enum关键字来定义枚举,一般是通过自定义类型 + const + iota来实现枚举。- 自定义类型 + const + iota
//自定义季节类型 type Season uint8 // iota给常量赋值 const ( Spring Season = iota Summer Autumn Winter )- 给自定义类型绑定方法,获取枚举对应的字符串
func (s Season) String() string { switch s { case Spring: return "spring" case Summer: return "summer" case Autumn: return "autumn" case Winter: return "winter" } return "" }
2、变量
2.1 变量简介
- 变量是用于存储值的位置,并且变量允许是运行过程中动态变更(和常量的区别,常量不允许变更),变量定义好之后,会给变量分配一个内存,用于存储值。
2.2 变量的声明
- Go中变量使用关键字
var定义,与Java不同的是,Go变量类型是后置的,也就是先定义变量名称,再定义变量类型。
var num int //num:变量名 int:变量类型
var str string //stri:变量名 string:变量类型
- 声明多个相同类型的变量
var num1,num2,num3 int //只需要一次变量类型
- 声明多个不同类型的变量,可以使用
()
var (
num int
str string
)
- 变量只声明,而不做赋值,变量默认值就是声明类型的零值。
2.3 变量的赋值
- 变量的赋值使用
=符号。
var num int
num = 1
//可以在声明时直接赋值
var str string = "go"
var name string
var age int
name,age = "golong",100 //可以多个变量一起赋值
-
短变量初始化(
:=),可省略var关键字和后置类型,由编译器自动推断类型。num := 2- 短变量初始化无法对一个已经赋值的变量进行变更,有一种情况除外,多变量一起赋值时,有一个新声明的变量。
var num = 2 num := 3 //编译器编译无法不通过 num,age := 4,23 //因age是新声明的变量,所以允许该操作- 短变量初始化只能在函数内部使用,函数外部还是只能
var关键字
2.4 变量的匿名
- 当一个变量不需要使用时,可以使用
_代替该变量。
// Open函数返回两个变量,当第二个变量后续无需使用时,可以用_替代,避免变量未使用导致编译无法通过。
file, _ := os.Open("readme.txt")
2.5 变量的交换
- Go中,交换两个变量的值,可以直接使用赋值运算符直接进行交换。
num1,num2 := 1,2
num1,num2 = num2,num1
- 变量的交换是先计算,再做交换的。
a, b, c := 0, 1, 1
a, b, c = b, c, a+b // a + b = 0 + 1,而不是1+1
//结果为 1,1,1
2.6 变量的比较
-
变量的比较有一个大前提,就是要做比较的两个变量类型必须是同一类型。
-
Go中不存在隐式类型转换。
-
内置的
min和max函数,go1.21版本之后,这两个函数用泛型重写,支持了其他类型的比较(原先只支持浮点型)- 布尔
- 数字
- 字符串
- 指针
- 通道 (仅支持判断是否相等)
- 元素是可比较类型的数组(切片不可比较)(仅支持判断是否相等)(仅支持相同长度的数组间的比较,因为数组长度也是类型的一部分,而不同类型不可比较)
- 字段类型都是可比较类型的结构体(仅支持判断是否相等)
-
标准库
cmp,不过仅支持有序类型的参数,在 go 中内置的有序类型只有数字和字符串。
import "cmp"
func main() {
cmp.Compare(1, 2)
cmp.Less(1, 2)
}
2.7 代码块
- 在函数内部,可以通过花括号建立一个代码块,每个代码块内,变量作用域是相互独立的。
func main() {
a := 1
{
a := 2
fmt.Println(a)
}
{
a := 3
fmt.Println(a)
}
fmt.Println(a)
}