基础篇
1、make和new的区别
共同点:都是给变量分配内存的,且在堆上分配内存
不同点:
- 作用变量不同: make只能用来分配slice,map,channel的数据;new可以分配任意类型的数据
- 返回类型不一样: new返回指向变量的指针,make返回变量本身
- new 分配的空间被清零。make 分配空间后,会进行初始化
var v *int
v = new(int)
*v = 8
fmt.Println(*v)
av := make([]int, 5)
2、数组和切片的区别
相同点:
- 只能存储一组相同类型的数据结构
- 都是通过下标来访问,并且有容量长度,长度通过 len 获取,容量通过 cap 获取
不同点:
- 数组是定长,访问和复制不能超过数组定义的长度,否则就会下标越界,切片长度和容量可以自动扩容
- 数组是值类型,切片是引用类型,每个切片都引用了一个底层数组,切片本身不能存储任何数据,都是这底层数组存储数据,所以修改切片的时候修改的是底层数组中的数据。切片一旦扩容,指向一个新的底层数组,内存地址也就随之改变
7、
golang 中解析 tag 是怎么实现的?反射原理是什么?(中高级肯定会问,比较难,需要自己多去总结)
type User struct {
name string `json:name-field`
age int
}
func main() {
user := &User{"John Doe The Fourth", 20}
field, ok := reflect.TypeOf(user).Elem().FieldByName("name")
if !ok {
panic("Field not found")
}
fmt.Println(getStructTag(field))
}
func getStructTag(f reflect.StructField) string {
return string(f.Tag)
}
反射是指在程序运行期对程序本身进行访问和修改的能力,程序在编译时变量被转换为内存地址,变量名不会被编译器写入到可执行部分,在运行程序时程序无法获取自身的信息。
Go语言中的反射是由 reflect 包提供支持的,它定义了两个重要的类型 Type 和 Value,任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成,并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 两个函数来获取任意对象的 Value 和 Type。
Go 中解析的 tag 是通过反射实现的。tag是啥:结构体支持标记,name string `json:name-field` 就是 `json:name-field` 这部分
gorm json yaml gRPC protobuf gin.Bind()都是通过反射来实现的
反射