一、值類型
值類型的數據直接包含值,當它們被賦值給一個新的變量或者作為參數傳遞給函數時,實際上是創建了原值的一個副本。這意味著對新變量的修改不會影響原始變量的值。
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)}
輸出: