文章目录
-
-
- [1. 值类型和引用类型都有哪些](#1. 值类型和引用类型都有哪些)
- [2. 值类型和引用类型的区别](#2. 值类型和引用类型的区别)
- [3. 变量是否等于nil](#3. 变量是否等于nil)
- [4. 能否进行等值比较](#4. 能否进行等值比较)
- [5. 能否不分配内存直接添加元素](#5. 能否不分配内存直接添加元素)
-
1. 值类型和引用类型都有哪些
值类型:int,string,bool,float,数组,结构体;
引用类型:切片,channel,map,接口类型,函数,指针。
2. 值类型和引用类型的区别
- 对于值类型来说:当我们将一个值类型的变量赋值 给另一个变量时,这个值会被复制。如果后续我们改变其中一个变量的值,另一个变量的值则不会受到影响。同样,当我们传递一个值类型的变量到函数 中时,函数会得到这个值的一个复制,而不是原始的值。
- 对于引用类型:当我们将一个引用类型的变量赋值 给另一个变量时,这个引用(也就是这个变量指向的内存地址)会被复制。所以,如果我们改变引用类型变量的值,所有引用这个地址的变量都会看到这个改变。同样,当我们传递一个引用类型的变量到函数中 时,函数会得到真实值的一个引用,所以函数内对其做的任何改变,调用者都能看到。
3. 变量是否等于nil
对于引用类型的变量如果只是var定义变量并且没有分配内存赋值,那么就是nil。
python
s1 := make([]int, 10)
var s2 []int
fmt.Println(s1 == nil) // false
fmt.Println(s2 == nil) // true
mp1 := make(map[int]int)
var mp2 map[int]int
fmt.Println(mp1 == nil) // false
fmt.Println(mp2 == nil) // true
ch1 := make(chan int, 5)
var ch2 chan int
fmt.Println(ch1 == nil) // false
fmt.Println(ch2 == nil) // true
var i interface{}
var j interface{}
j = 5
fmt.Println(i == nil) // true
fmt.Println(j == nil) // false
4. 能否进行等值比较
结论:
函数类型、map 类型和切片只支持与 nil的比较,而不支持同类型两变量的比较,否则会编译报错。
channel类型,interface类型、数组类型支持两个相同变量比较。
struct比较特殊,一定情况下可以进行等值比较。
原因:
- 切片、map 和函数:只能与 nil 进行比较,它们之间无法进行相互比较。这是由于这些类型的数据结构是动态的,在进行比较时需要做复杂的深度比较,会非常耗时。例如,即使两个切片包含完全相同的元素,它们也可能在内存中的不同位置。
- channel:可以进行相互比较也可以与nil进行比较。这主要是因为比较的是channel的引用(即内存地址),而不是channel中的数据。如果两个channel引用相同,那么比较结果为true。
- 接口:接口类型既可以与nil进行比较,也可以进行相互比较。如果两个接口值具有相同的动态类型,并且动态值相等,那么两个接口值将被视为相等。
- 数组:如果两个数组类型定义相同(即长度和元素类型都相同),那么它们就可以进行比较。比较会按照元素顺序进行,一旦找到第一对不相等的元素,比较就会停止、还要注意,尽管可比较,但是比较大数组可能会非常耗费性能,因为必须检查每个元素是否相等。因此,通常建议仅在必要时对数组进行比较。
- 结构体:相同类型(属性类型相同且属性顺序相同)的结构体才能进行比较,并且只有结构体中的字段类型都是可以支持比较的类型是才可以进行等值比较。
5. 能否不分配内存直接添加元素
切片可以通过下面的操作使用,也可以make函数创建切片变量并初始化。
python
var s []int
s = append(s, 100)
map不能直接var定义完后使用,需要make函数初始化才能使用。
channel也不能不能直接var定义完后使用,需要make函数初始化才能使用。