数据类型概览
基础数据类型
数值型变量的默认值是0,字符串的默认值是空字符串,布尔型变量的默认值是false,引用类型、函数、指针、接口的默认值是nil。数组的默认值取每个元素对应类型的默认值,结构体的默认值取每个成员变量对应类型的默认值。
类型 | 长度(字节) | 默认值 | 说明 |
---|---|---|---|
bool | 1 | false | |
byte | 1 | 0 | uint8,取值范围[0,255] |
rune | 4 | 0 | Unicode Code Point, int32 |
int, uint | 4或8 | 0 | 32 或 64 位,取决于操作系统 |
int8, uint8 | 1 | 0 | -128 ~ 127, 0 ~ 255 |
int16, uint16 | 2 | 0 | -32768 ~ 32767, 0 ~ 65535 |
int32, uint32 | 4 | 0 | -21亿~ 21亿, 0 ~ 42亿,rune是int32 的别名 |
int64, uint64 | 8 | 0 | |
float32 | 4 | 0.0 | |
float64 | 8 | 0.0 | |
complex64 | 8 | ||
complex128 | 16 | ||
uintptr | 4或8 | 以存储指针的 uint32 或 uint64 整数 | |
例: |
package main
import "fmt"
func test01() {
var a int
var b string
var c bool
var d byte
var e rune
fmt.Printf("a的默认值=%d\nb的默认值=%s\nc的默认值=%t\nd的默认值=%c\ne的默认值=%c\n", a, b, c, d, e)
}
func main() {
test01()
}
//输出:
//a的默认值=0
//b的默认值=
//c的默认值=false
//d的默认值=
//e的默认值=
复合数据类型
类型 | 默认值 | 说明 |
---|---|---|
array | 取每个元素对应类型的默认值 | 值类型 |
struct | 取每个成员变量对应类型的默认值 | 值类型 |
string | “” | UTF-8 字符串 |
slice | nil | 引用类型 |
map | nil | 引用类型 |
channel | nil | 引用类型 |
interface | nil | 接口 |
function | nil | 函数 |
自定义类型
类型别名
package main
import "fmt"
func test01() {
type a = int
type b = bool
type c = string
var d a
var e b
var f c
fmt.Printf("d的类型=%T\ne的类型=%T\nf的类型=%T\n", d, e, f)
}
func main() {
test01()
}
//代码输出结果:
//d的类型=int
//e的类型=bool
//f的类型=string
自定义类型
package main
import "fmt"
type User struct {
ID int
name string
}
type ms map[string]string
func test01() {
var a User
var b ms
fmt.Printf("a的类型=%T\nb的类型=%T\n", a, b)
}
func main() {
test01()
}
//代码输出结果:
//a的类型=main.User
//b的类型=main.ms
数组
数组是块连续的内存空间,在声明的时候必须指定长度,且长度不能改变。所以数组在声明的时候就可以把内存空间分配好,并赋上默认值,即完成了初始化。
一维数组:
var arr1 = [5]int{} //数组必须指定长度和类型,且长度和类型指定后不可改变
var arr2 = [4]int{}
var arr3 = [3]int{1, 2} //给前2个元素赋值,第三个没赋值为该类型的默认值
var arr4 = [5]string{0: "liangqd", 2: "test1", 4: "test2"} //指定index赋值
var arr5 = [...]int{1, 2, 3, 4, 5} //根据{}里元素的个数推断出数组的长度
二维数组
package main
import "fmt"
func test01() {
var arr1 = [2][3]int{{1, 2}, {3, 4}}
var arr2 = [...][2]int{{5, 6}, {7, 8}, {9, 10}}
fmt.Println(arr1, arr2, arr2[1][0], arr2[0][1])
}
func main() {
test01()
}
//代码输出结果:
//[[1 2 0] [3 4 0]] [[5 6] [7 8] [9 10]] 7 6
访问数组里的元素
遍历数组
package main
import "fmt"
//遍历一维数组
func test01() {
var arr1 = [5]int{1, 3, 5, 7, 9}
for index, number := range arr1 { //range遍历数据会返回两个值,第一个是下标,另一个是下标对应的值
fmt.Printf("下标%d的元素为%d\n", index, number)
}
}
//遍历二维数组
func test2() {
var arr1 = [3][2]int{{1, 2}, {3, 4}, {5, 6}}
for index, number := range arr1 {
for row, array := range number {
fmt.Printf("下标%d的数组为%d,二维元素下标为%d的元素为%d\n", index, number, row, array)
}
}
}
func main() {
test01()
test2()
}
//代码输出结果:
//下标0的元素为1
//下标1的元素为3
//下标2的元素为5
//下标3的元素为7
//下标4的元素为9
//下标0的数组为[1 2],二维元素下标为0的元素为1
//下标0的数组为[1 2],二维元素下标为1的元素为2
//下标1的数组为[3 4],二维元素下标为0的元素为3
//下标1的数组为[3 4],二维元素下标为1的元素为4
//下标2的数组为[5 6],二维元素下标为0的元素为5
//下标2的数组为[5 6],二维元素下标为1的元素为6
在数组上调用cap()函数表示capacity容量,即给数组分配的内存空间可以容纳多少个元素;len()函数代表length长度,即目前数组里有几个元素。由于数组初始化之后长度不会改变,不需要给它预留内存空间,所以len(arr)==cap(arr)。对于多维数组,其cap和len指第一维的长度。
数组的长度和类型都是数组类型的一部分,函数传递数组类型时这两部分都必须吻合。go语言没有按引用传参,全都是按值传参,即传递数组实际上传的是数组的拷贝,当数组的长度很大时,仅传参开销都很大。如果想修改函数外部的数组,就把它的指针(数组在内存里的地址)传进来。
package main
import "fmt"
func test01(arr [3]int) {
arr[2] = 20
fmt.Println(arr[2])
}
func test02(arr *[3]int) {
arr[0] = 100
fmt.Println(arr[0])
}
func main() {
arrM := [3]int{1, 2, 3}
test01(arrM)
fmt.Println(arrM)
test02(&arrM)
fmt.Println(arrM)
}
//代码输出结果:
//20
//[1 2 3]
//100
//[100 2 3]
切片
暂缓,打游戏去