Pointers(指標)

介紹

指標:用來儲存記憶體位址的變數。

使用的運算子

  • * : 宣告指標、對指標取值
  • & : 對變數取位址

宣告

var pointA *int32
var pointB *int32 = nil
fmt.Println(pointA) // <nil>
fmt.Println(pointB) // <nil>

錯誤的初始化
// cannot use 0 (type int) as type *int in assignment
var pointC *int = 0

範例一

var variableA int32 = 1234
fmt.Println(variableA) // 1234
fmt.Println(&variableA) // 0xc08200c380 (記憶體位置是變動的)

var variableB int32 = 5678
fmt.Println(variableB) // 5678
fmt.Println(&variableB) // 0xc08200c3a0

var variableC *int32 = &variableA
fmt.Println(variableC) // 0xc08200c380
fmt.Println(*variableC) // 1234
fmt.Println(&variableC) // 0xc08202a028

variableC = &variableB
fmt.Println(variableC) // 0xc08200c3a0
fmt.Println(*variableC) // 5678

*variableC = 555
fmt.Println(variableC) // 0xc08200c3a0
fmt.Println(*variableC) // 555
fmt.Println(variableA) // 1234
fmt.Println(variableB) // 555

範例二

// 不同型別是不可以賦予的
var variableA int32 = 1234
var variableB int64 = 5678
var variableC *int32
variableC = &variableA
// cannot use &variableB (type *int64) as type *int32 in assignment
//variableC = &variableB

範例三

// 1.陣列指標的長度 是會被檢查的.
// 2.變量名不等於陣列開始指標.

var arrayA [5]int = [5]int{1,2,3,4,5}
fmt.Println(arrayA, &arrayA) // [1 2 3 4 5] // &[1 2 3 4 5]
// 連續記憶體
fmt.Println(arrayA[0], &arrayA[0]) // 1 0xc082005f50
fmt.Println(arrayA[1], &arrayA[1]) // 2 0xc082005f58
fmt.Println(arrayA[2], &arrayA[2]) // 3 0xc082005f60
fmt.Println(arrayA[3], &arrayA[3]) // 4 0xc082005f68
fmt.Println(arrayA[4], &arrayA[4]) // 5 0xc082005f70

// 陣列指標    
var pointX *[5]int = &arrayA
fmt.Println(pointX, &pointX, *pointX) // &[1 2 3 4 5] 0xc08202a030 [1 2 3 4 5]

fmt.Println(reflect.TypeOf(arrayA)) // [5]int
fmt.Println(reflect.TypeOf(arrayA[0])) // int
fmt.Println(reflect.TypeOf(pointX)) // *[5]int
fmt.Println(reflect.TypeOf(pointX[0])) // int

// 錯誤的宣告 
// 1.陣列指標的長度 是會被檢查的
// 2.變量名不等於陣列開始指標
// cannot use &arrayA (type *[5]int) as type *[]int in assignment
// var pointX *[]int = &arrayA
// cannot use &arrayA (type *[5]int) as type *[4]int in assignment
// var pointX *[4]int = &arrayA
// cannot use arrayA (type [5]int) as type *int in assignment
// var pointX *int = arrayA
// cannot use &arrayA (type *[5]int) as type *int in assignment
// var pointX *int = &arrayA

// 陣列指標的操作 等同陣列
pointX[0] = 2;
fmt.Println(arrayA, pointX) // [2 2 3 4 5] &[2 2 3 4 5]
// cannot use 2 (type int) as type [5]int in assignment
// *pointX = 2;