数组
固定大小
- 初始化
arr1 := [3]int{1, 2, 3}
arr2 := [...]int{1, 2, 3}
var arr3 []int
var arr4 [4]int
切片
长度是动态的
- 初始化
arr[0:3]
slice := []int{1,2,3}
slice := make([]int, 10)
- len和cap
- len是获取切片、数组、字符串的长度——元素的个数
- cap是获取切片的容量——切片底层数组的长度
res := [5]int{1, 2, 3}
res1 := res[1:4]
fmt.Println(res1)
fmt.Println("1111", cap(res1))
3. 用法
- 扩容:append
- 拷贝切片(后面再啃)
哈希表(后面再啃)
读取
//方法一
hash[key] = value
delete(hash,key)
//方法二
for k,v := range hask{
}
字符串
- 不可以直接修改,需要转换成字节数组
str := "hello"
newStr := []byte(str)
fmt.Println(str)
fmt.Println(newStr)
函数调用
接口
Go 语言中的接口是隐式实现的,也就是说,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。因此,我们可以通过将接口作为参数来实现对不同类型的调用,从而实现多态。
type Shape interface {area() float64
}
type Rectangle struct {width float64height float64
}func (r Rectangle) area() float64 {return r.width * r.height
}
反射
- 三大法则
- 从 interface{} 变量可以反射出反射对象;
- 从反射对象可以获取 interface{} 变量;
- 要修改反射对象,其值必须可设置;
第一法则
举例:
func main() {author := "draven"fmt.Println("TypeOf author:", reflect.TypeOf(author))fmt.Println("ValueOf author:", reflect.ValueOf(author))
}
对于不同的类型,我们也可以调用不同的方法获取相关信息:
- 结构体:获取字段的数量并通过下标和字段名获取字段 StructField;
- 哈希表:获取哈希表的 Key 类型;
- 函数或方法:获取入参和返回值的类型;
第二法则
举例:
func main() {i := 1v := reflect.ValueOf(&i)v.Elem().SetInt(10)fmt.Println(i)
}$ go run reflect.go
10
- 调用 reflect.ValueOf 获取变量指针;
- 调用 reflect.Value.Elem 获取指针指向的变量;
- 调用 reflect.Value.SetInt 更新变量的值:
由于 Go 语言的函数调用都是值传递的,所以我们只能只能用迂回的方式改变原变量:
先获取指针对应的 reflect.Value,再通过 reflect.Value.Elem 方法得到可以被设置的变量,我们可以通过下面的代码理解这个过程:
func main() {i := 1v := &i*v = 10
}
如果不能直接操作 i 变量修改其持有的值,我们就只能获取 i 变量所在地址并使用 *v 修改所在地址中存储的整数。