常量,就是在程序编译阶段就确定下来的值,而程序在运行时则无法改变该值。在go中使用const
定义常量。
const constVarName [type]= value
Go的常量定义可以限定常量类型,但不是必需的。如果定义常量时没有指定类型,那么它是无类型常量。只要这个常量在相应类型的值域范围内,就可以作为该类型的常量,比如常量-12,它可以赋值给int、uint、int32、int64、float32、float64、complex64、complex128等类型的变量。
从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间。在go中使用var
定义变量。
var varName type
var varName1,varName2 type
,varName1和varName2的类型相同var (
varName1 type1
varName2 type2
)
:=
简短声明:varName := value
,变量varName的类型会被自动推导为value的类型var varName type=value
var varName =value
,自动推导变量类型var varName1, varName2, varName3 type= value1, value2, value3
var varName1, varName2, varName3 = value1, value2, value3
,自动推导变量类型一般就是声明后就可以进行赋值,和其他语言一致。特别的是,可进行多重复值,varName1,varName2=vale1,value2
,varName1和varName2已经声明。
_
是一个特殊的变量名,任何赋予它的值后会被丢弃。
类型名称 | 有无符号 | bit数 |
---|---|---|
int8 | Yes | 8 |
int16 | Yes | 16 |
int32 | Yes | 32 |
int64 | Yes | 64 |
uint8 | No | 8 |
uint16 | No | 16 |
uint32 | No | 32 |
uint64 | No | 64 |
int | Yes | 等于cpu位数 |
uint | No | 等于cpu位数 |
rune | Yes | 与 int32 等价 |
byte | No | 与 uint8 等价 |
uintptr | No | - |
rune 类型是 Unicode 字符类型,和 int32 类型等价,通常用于表示一个 Unicode 码点。rune 和 int32 可以互换使用。
byte 是uint8类型的等价类型,byte类型一般用于强调数值是一个原始的数据而不是 一个小的整数。
uintptr 是一种无符号的整数类型,没有指定具体的bit大小但是足以容纳指针。 uintptr类型只有在底层编程是才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。
不管它们的具体大小,int、uint和uintptr是不同类型的兄弟类型。其中int和int32也是 不同的类型, 即使int的大小也是32bit,在需要将int当作int32类型的地方需要一个显式 的类型转换操作,反之亦然。
有符号整数采用 2 的补码形式表示,也就是最高 bit 位用作表示符号位,一个 n bit 的有 符号数的值域是从 -2^{n-1} 到 2^{n-1}−1。例如,int8类型整数的值域是从-128 到 127, 而uint8类型整数的值域是从0到255。
- Go语言中,浮点数分为
float32
和float64
两种类型。- 只有整数部分的浮点数,要加小数点标识,例如浮点数1的标识为1.0。
- 对于整数字面量和浮点数字面量,Go根据使用的场合,会自动 整数->浮点数或浮点数->整数 转换。
- 常量
math.MaxFloat32
表示float32能表示的最大数值,大约是3.4e38;对应的math.MaxFloat64
常量大约是1.8e308。它们分别能表示的最小值近似为1.4e-45和4.9e-324。math.IsNaN
用于测试一个数是否是非数NaN,math.NaN
则返回非数对应的值。
- Go语言中,复数分为
complex64
和complex128
,分别对应float32和float64两种浮点数精度,可以用0+1i
的格式表示。- 内置的complex函数用于构建复数,内建的real和imag函数分别返回复数的实部和虚部。
Go语言中,布尔值的类型为
bool
,值是true
或false
。
一个字符串是一个不可改变的字节序列。
- 原生字符串:使用反引号代替双引号。
Go语言中数组是一个值类型(value type),是真真实实的数组,而不是一个指向数组内存起始位置的指针,也不能和同类型的指针进行转化,这一点严重不同于C语言。所有的值类型变量在赋值和作为参数传递时都将产生一次复制动作。如果将数组作为函数的参数类型,则在函数调用时该参数将发生数据复制。因此,在函数体中无法修改传入的数组的内容,因为函数内操作的只是所传入数组的一个副本。
var arr [arrLength]type
arr为数组变量名,arrLength为数组的长度,type为数组中元素类型。数组长度在定义后就不可更改,组的长度是该数组类型的一个内置常量,可以用Go语言的内置函数len()
来获取。
常见的声明方式如下:
var a [5]byte //长度为5的数组,每个元素为一个字节
var b [2*N] struct { x, y int5 } //复杂类型数组
var c [5]*int // 指针数组
var d [2][3]int //二维数组
var e [2][3][4]int //等同于[2]([3]([4]int))
初始化
- 先声明再初始化
例如:a = {'1','2','3'}
,d = {{1,2,3},{4,5,6}}
- 直接声明并初始化
a := [3]byte{'1', '2', '3'}
,声明并初始化一个长度为3的byte数组
a := [...]byte{'1', '2', '3'}
,可以省略长度而采用...
的方式,Go会自动根据元素个数来计算长度
d := [2][3]int{[3]int{1,2,3},[3]int{4,5,6}}
d := [2][3]int{{1,2,3},{4,5,6}}
,如果内部的元素和外部的一样,那么上面的声明可以简化,直接忽略内部的类型
访问数组元素
- 使用数组下标来访问数组中的元素,例如
arr[i]
。数组下标从0
开始,len(arr)-1
则表示最后一个元素的下标。- 特别的访问方式,通过
range
访问。range具有两个返回值,第一个返回值i是元素的数组下标,第二个返回值v是元素的值,示例如下(range(arr)
和range arr
效果一样)。
for i, v := range arr {
fmt.Println(i, v)
}
切片基于数组构建,但是提供更强的功能和便利。切片的类型是 []T
,T
是切片元素的类型。和数组不同的是,切片没有固定的长度。
切片的字面值和数组字面值很像,不过切片没有指定元素个数,例如:
letters := []string{"a", "b", "c", "d"}
切片可以内置函数 make 创建,函数签名为:
func make([]T, len, cap) []T
T
代表被创建的切片元素的类型。函数make
接受一个类型、一个长度和一个可选的容量参数。调用make
时,内部会分配一个数组,然后返回数组对应的切片。示例:
s := make([]byte, 5)
根据数组创建切片:
arr := [5]int{1,2,3,4,5}
slices := arr[1:3]
字典类型变量的定义和声明:var mapVarName map[keyType]valueType
声明并赋值
mm := map[int]string{1: "a", 2: "b", 3: "c"}
取值
tmp := mm[2] // 通过key取value
// 或者
val,existed :=mm[2] // existed为tru或false,表示指定key的键值对是否存在
赋值
mm[1] = "d"
删除
delete(mm, 4) // 删除以4为键的键值对
type structName struct {
varName1 type1
varName2 type2
}
type interfaceName interface {
Method1(paramType1,...) (returnType1,...)
}
type anotherTypeName type
,anotherTypeName和type指明的是同一种类型。