指標
本章圍繞字串、數字、陣列、切片、map、channel、結構體與指標賦值及函式傳參的應用剖析
字串
字串本身也是StringHeader的結構體,包含Data指標與字串長度,如下
type StringHeader struct { Data uintptr Len int}Data指向的記憶體地址不可更改,字串賦值和傳參只是拷貝了StringHeader中Data和Len的值
package mainimport "fmt"func main() { str := "Hello World!" var data string data = https://www.cnblogs.com/lianzhilei/p/str // 拷貝str中Data與Len fmt.Println(data) data ="Hello Go!" // 修改data的值 在記憶體中生成新的StringHeader結構體 并賦值給data fmt.Println(data) // str記憶體未改變 fmt.Println(str)}//Hello World!//Hello Go!//Hello World!當宣告變數為字串指標時,變數賦值時物件一定是字串記憶體地址,函式傳參時拷貝的也是記憶體地址而已
package mainimport "fmt"func main() { str := "Hello World!" var ptr *string // 錯誤方法 str是字串型別非指標型別 //ptr = str // 正確方式 獲取str的地址 賦值給ptr ptr = &str fmt.Println(ptr) fmt.Println(*ptr)}//0xc0000421c0//Hello World!
數字
數字未找到對應的結構體,數字型別賦值、指標、函式傳參與字串一致,不可修改(修改等同于重新賦值)
package mainimport "fmt"func main() { number := 10 var ptr *int // 錯誤方法 str是字串型別非指標型別 //ptr = str // 正確方式 獲取str的地址 賦值給ptr ptr = &number fmt.Println(ptr) fmt.Println(*ptr)}//0xc00000a0b8//10
陣列
陣列賦值、函式傳參時,進行都是記憶體拷貝,資料都會拷貝一份,新的陣列修改不影響被賦值的陣列
package mainimport "fmt"func main() { list1 := [4] int{1,2,3,4} list2 := list1 list2[0] =100 fmt.Println(list1) fmt.Println(list2)}//[1 2 3 4]//[100 2 3 4]陣列指標,指標修改時不需要加*的;修改時,原陣列更改
package mainimport "fmt"func main() { list := [4]int{1,2,3,4} // 宣告時指定陣列大小 var ptr *[4]int ptr = &list // 錯誤賦值 //*ptr[0] =100 // 正確方式 ptr[0] = 100 fmt.Println(list) fmt.Println(*ptr)}//[100 2 3 4]//[100 2 3 4]
切片
切片結構體 SliceHeader 如下
type SliceHeader struct { // 指向陣列記憶體地址 賦值時拷貝的是陣列地址 Data uintptr // 長度 Len int // 申請空間 Cap int}賦值、copy、函式傳參時只是拷貝了結構體中的變數,詳情Go語言【資料結構】切片
package mainimport "fmt"func main() { slice1 := []int{1,2,3,4} slice2 := slice1 slice2[0] =100 fmt.Println(slice1) fmt.Println(slice2)}//[100 2 3 4]//[100 2 3 4]切片指標,下面方式都不可以修改
package mainimport "fmt"func main() { slice1 := []int{1,2,3,4} var ptr *[]int ptr = &slice1 // 下面兩種方式都不可以修改 ptr[0] =100 *ptr[0] =100 fmt.Println(slice1) fmt.Println(*ptr)}//[1 2 3 4]//[1 2 3 4]
channel
通道在賦值時,指向的都是同一塊記憶體地址
package mainimport "fmt"func main() { chan1 := make(chan string,1) chan2 := chan1 chan2 <- "hello" data := <-chan1 fmt.Println(data) // 指向同一塊地址 fmt.Println(chan1) fmt.Println(chan2)}//hello//0xc000088000//0xc000088000同時,通道也支持指標
package mainimport "fmt"func main() { chan1 := make(chan string,1) chan2 := &chan1 *chan2 <- "hello" data := <-chan1 fmt.Println(data) fmt.Println(chan1) fmt.Println(chan2)}//hello//0xc000038060//0xc000006028
結構體
那么重點來了,結構體賦值和指標有何區別,先看戲結構體生成的三種方式,其中第二種方式和第三中方式一致
package mainimport "fmt"type Phone struct { color string name string}func main() { // 第一種生成方式 生成結構體物件 phone1 :=Phone{"Red","Iphone"} fmt.Println(phone1.color) fmt.Println(phone1.name) fmt.Println(phone1) // 第二種生成方式 生成結構體指標 phone2 :=&Phone{"Red","Iphone"} fmt.Println(phone2.color) fmt.Println(phone2.name) fmt.Println(phone2) // 第三種生成方式 生成結構體指標 phone3 := new(Phone) phone3.color = "Red" phone3.name = "Iphone" fmt.Println(phone3.color) fmt.Println(phone3.name) fmt.Println(phone3)}//Red//Iphone//{Red Iphone}//Red//Iphone//&{Red Iphone}//Red//Iphone//&{Red Iphone}結構體賦值,等同于拷貝了結構體中的變數,函式傳參與賦值一樣
package mainimport "fmt"type Phone struct { color string name string}func main() { // 賦值 phone1 :=Phone{"Red","Iphone"} phone2 := phone1 phone2.color = "Green" fmt.Println(phone1.color) fmt.Println(phone2.color)}//Red//Green而指標只是拷貝了結構體的記憶體地址,修改會影響原來的值
package mainimport "fmt"type Phone struct { color string name string}func main() { // 賦值 phone1 :=&Phone{"Red","Iphone"} phone2 := phone1 phone2.color = "Green" fmt.Println(phone1.color) fmt.Println(phone2.color)}//Green//Green
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/71587.html
標籤:Go
上一篇:golang面對物件
