網頁

2022/3/10

Golang 可取址運算元 addressable operands

Go的&address operators(取址運算子)可用來取得其後運算元(operand)的記憶體位置又稱為pointer(指標/指針),但注意運算元必須是可取址的(addressable)否則無法通過編譯。


&的基本用法請參考「Golang Pointers 指標簡單範例」、「Golang Pointer符號整理」。


Addressable

&可取址的對象包括:

  • 變數(variable)
  • 間接指標(pointer indirection)
  • Slice索引操作(slice indexing operation)
  • 可取址的陣列索引操作(addressable array indexing operation)
  • 可取址struct的屬性選取(addressable struct field selector)
  • Composite literal

main.go

package main

import "fmt"

type Employee struct {
    ID   int64
    Name string
    Age  int
}

func main() {
    // variable
    i := 3
    fmt.Println(&i)

    // pointer indirection
    var n *int = &i
    fmt.Println((&*n))

    // slice indexing operation
    sl := []int{1, 2, 3}
    fmt.Println(&sl[0])

    // addressable array indexing operation
    arr := [3]string{"a", "b", "c"}
    fmt.Println(&arr[1])

    // addressable struct field selector
    emp := Employee{ID: 1, Name: "John", Age: 33}
    fmt.Println(&emp.ID)

    // composite literals
    fmt.Println(&[]int{1, 2, 3})
    fmt.Println(&map[int]string{1: "a", 2: "b"})
    fmt.Println(&Employee{}) // struct literal is unaddressable, but is legal because of syntax sugar
    // equivalent to tmp := Employee{}; &tmp
}


Unaddressable

&不可取址的(unaddressable)對象包括:

  • 常數(constant)
  • 實字(literals)
  • 字串的字元
  • map的元素
  • 函式(function)
  • 方法(method)
  • 型別轉換(type conversion)

以下皆出現編譯錯誤。

main.go

package main

import "fmt"

const x int = 1

type Counter int

func (c *Counter) Count() int {
    *c++
    return int(*c)
}

func add(x, y int) int {
    return x + y
}

func main() {
    // unaddressable
    fmt.Println(&x)                         // constant
    fmt.Println(&"hello")                   // literal
    fmt.Println(&"hello"[0])                // string's char
    fmt.Println(&map[int]string{1: "a"}[0]) // map's element
    fmt.Println(&add(1, 2))                 // function

    var c Counter = 1
    fmt.Println(&c.Count()) // method
    fmt.Println(&int(c))    // type convert
    
    var i interface{} = "abc"
	fmt.Println(&i.(string)) // type assertion
}


沒有留言:

張貼留言