一、值类型
值类型的数据直接包含值,当它们被赋值给一个新的变量或者作为参数传递给函数时,实际上是创建了原值的一个副本。这意味着对新变量的修改不会影响原始变量的值。
Go中的值类型包括:
- 基础类型:int,float64,bool,string等。
- 数组([N]Type):固定大小的元素序列,所有元素必须同一类型。
- 结构体(struct): 自定义的复合类型。
测试:传入上述值类型是否能改变原始变量值
package mainimport "fmt"func modifyString(str string) {str = "字符串222"
}// 注意这里arr 类型为[5]int,因为数据长度是数组类型的一部分
func modifyArr(arr [5]int) {arr[0] = 100
}type User struct {name stringage int
}func modifyUser(user User) {user.age = 20
}func main() {// 测试stringstrstr := "字符串111"modifyString(strstr)fmt.Println(strstr)//测试数组arr := [5]int{1, 2, 3, 4, 5}modifyArr(arr)fmt.Println(arr)// 测试结构体user := User{name: "xiaoming",age: 18,}modifyUser(user)fmt.Println(user)
}
输出:
二、引用类型
引用类型不存储值本身,而是存储一个指向实际值的地址。当你将引用类型的变量赋值给新的变量或传递给函数时,你实际上是在共享同一个底层数据。因此,通过任何持有引用的变量所做的更改都将反映在其他所有引用上。
Go中的引用类型包括:
- 切片(slice)
- 映射(map)
- 通道(channel)
- 指针(pointer)
测试:传入上述引用类型能否改变原始的值
package mainimport ("encoding/json""fmt"
)func modifySlice(slice []int) {slice[0] = 100
}func modifyMap(customeMap map[string]string) {customeMap["a"] = "xxx"
}func modifyChannel(ch chan int) {// 向channel发送数据ch <- 42
}func modifyPtr(ptr *int) {*ptr = 20 // 修改指针指向的值
}func main() {// 测试切片slice := []int{1, 2, 3}modifySlice(slice)fmt.Println(slice)// 测试mapcustomeMap := map[string]string{"a": "a","b": "b",}modifyMap(customeMap)jsonBytes, err := json.Marshal(customeMap)if err != nil {fmt.Println(err)}fmt.Println(string(jsonBytes))// 测试channel// 创建一个无缓冲的channel,用于传输int类型的数据ch := make(chan int)// 开启一个新的goroutine,在其中调用modifyChannel函数go modifyChannel(ch)// 从channel接收数据并打印value := <-chfmt.Println("channel接收数据:", value)// 测试指针var ptr *int = new(int)fmt.Println("ptr初始值:", *ptr)modifyPtr(ptr)fmt.Println("ptr修改后:", *ptr)}
输出: