类型与复合类型
从基本类型走到 slice、map、struct 与指针入门。
基本类型
常见内建类型:
- 整数:
int、int8…int64、uint…(默认写int即可) - 浮点:
float32、float64 - 布尔:
bool - 字符串:
string(不可变字节序列) byte(=uint8)、rune(=int32,表示 Unicode 码点)
var (
i int = 42
f float64 = 3.14
b bool = true
s string = "go"
)
类型转换必须显式:float64(i),没有隐式拓宽。
array 与 slice
数组长度是类型的一部分,用得少;日常几乎都用 slice:
var arr [3]int = [3]int{1, 2, 3} // 数组
s := []int{1, 2, 3} // slice 字面量
s = append(s, 4) // 追加,可能换底层数组
fmt.Println(len(s), cap(s)) // 长度与容量
切片操作:
a := []int{0, 1, 2, 3, 4}
b := a[1:3] // [1 2],与 a 共享底层数组
b[0] = 99
fmt.Println(a) // [0 99 2 3 4]
预分配:make([]int, 0, 16)(长度 0、容量 16)。nil slice 可 append,len 为 0。
map
m := map[string]int{"a": 1}
m["b"] = 2
v, ok := m["c"] // 不存在时 v 为零值,ok == false
delete(m, "a")
- 用
make(map[string]int)或字面量创建;未初始化的var m map[string]int是nil,不能写只能读「不存在」 - 遍历顺序不保证稳定
for k, v := range m {
fmt.Println(k, v)
}
struct
type User struct {
Name string
Age int
}
u := User{Name: "xiping", Age: 18}
u.Age++
fmt.Println(u.Name)
可嵌套匿名字段(组合,进阶「接口与组合」会展开)。字段导出同样看首字母大小写。
指针入门
x := 10
p := &x // *int,指向 x
*p = 20 // 通过指针改值
fmt.Println(x) // 20
- Go 没有指针运算(不能
p++遍历内存) - 结构体常用指针接收者避免拷贝、允许修改(见「函数与方法」)
- 零值指针是
nil;解引用nil会 panic
type Point struct{ X, Y int }
p := &Point{X: 1, Y: 2}
p.X = 3 // 语法糖,等价 (*p).X
小结
- 显式转换;日常容器用 slice / map
- slice 注意共享底层数组;
append可能换底层 - map 用
v, ok := m[k]判断存在 - struct + 指针是组织数据的基本方式