[TOC]
### **对比**
Go语言的数据类型有 值类型 与 引用类型 两种。
* 值类型:在初始化、赋值时,两个变量互不影响;参数传递时,传递的是一个副本
* 引用类型:在初始化、赋值时,两个变量实际是同一个;参数传递时,传递的是变量本身。
在Go语言中,只有slice、map、interface、channel是引用类型,其他的都是值类型。
### **示例**
##### **值类型**
举个例子,数组array类型是值类型,那么在使用相同的类型的变量初始化另一个变量时,两个变量互不影响,如下array1与array2是两个不同的数组:
```
array1 := [10]int64{}
array2 := array1
```
在赋值时,只是把array1的内容拷贝到array2中,array1的修改不会再影响array2
```
array1 := [10]int64{1,2}
var array2 [10]int64{}
array2 = array1
array1[0] = 100 // array2[0] 不会变
```
##### **引用类型**
切片是引用类型,所以当使用一个切片初始化另一个切片时,两个切片实际是同一个
```
slice1 := make([]int64, 1, 10) // 初始化一个len为1,cap为10的切片
slice2 := slice1
slice1[0] = 1 // slice2[0] 也会变成1
```
### **直观判断**
上面我们已经列举了所有的引用类型,但是我们如何直观地判断一个数据类型是值类型还是引用类型呢?
其实,我们可以通过声明语义和赋值来判断。
比如,数组的底层其实有一个固定指针ptr和长度len两个变量。数组在声明的时候(`var array1 [10]int64`),必须指定长度,然后系统会在栈空间内分配一个内存空间;也就是说,声明语义完成后,ptr和len的值已经固定了。当我们声明另一个数组时(`var array2 [10]int64`),array2的地址空间和array1是不一样的,而且两个数组的底层ptr又是不能变的,所以赋值的时候,就不能把array2.ptr赋值为array1.ptr,而只能把array2的10个数据拷贝到array1的地址空间中。这样子一推断,数组只能是值类型。
**Q:如果某种类型的变量只声明,声明后该变量的值为nil,是否能说明这种类型为引用类型?**
- 环境安装
- 安装go
- vscode
- 第一个Go程序
- vscode-go插件
- Goland
- 数据类型
- 基本数据类型
- string
- array
- slice
- map
- struct
- interface
- channel
- 类型转换
- 指针
- 值类型与引用类型
- make和new的区别
- 类型别名
- 枚举
- Go语言基础
- 变量
- 常量
- 条件语句
- 循环语句
- 函数
- 运算符
- 错误处理
- Error
- Panic-Defer-Recover
- Go语言的包
- Import语法
- 依赖管理与Go命令
- Go源码文件组织结构
- 依赖管理工具简介
- Go-Module
- Go-Module最佳实践
- Go命令
- Go-Module-FAQ
- K8S开发指南
- 从外面访问K8S
- K8S的Watch机制
- client-go
- informer
- HTTP编程
- Client请求
- Server
- Header参数
- Query参数
- Body参数
- http包中的常量
- 常用包
- encoding/json
- net
- vishvananda/netlink
- containernetworking/plugins/pkg/ns
- strconv
- 编程练习
- 冒泡排序
- Go环境变量
- GOPROXY
- Go环境变量介绍
- 交叉编译
- 参考
- 并发
- context
- FAQ
- 测试