接下來進入到 golang 的 struct & pointer,如果有學過 C 的應該挺熟悉的這兩個 keyword,畢竟 golang 是有號稱21世紀的C語言,不熟悉的也沒關係,可以把它當作像一般常見的 OOP (Object-oriented programming),裡面會看到 class 來看待它,pointer的話就要稍微做一下功課才有辦法知道它的用意。

struct 宣告

package main

import (
	"fmt"
)

type Info struct {
	Age  int
	Name string
}

func main() {

	fmt.Println(Info{Age: 18, Name: "syhlion"})
}

https://play.golang.org/p/N3kKhhD8E7y

指標

何謂指標? 指標就是只到記憶體的位置,並不是值接存值

Pointer ref wiki

如上圖所述,pointer 只是指出該變數家裡的「住址」,並不是該變數的值,在 golang 裡面,要取「址」需要用 & 這個符號。 * 號則是返回該『位址』的值

package main

import (
	"fmt"
)



func main() {
	var a int
	a = 15

	fmt.Println(&a)
}

https://play.golang.org/p/X-lETZ5ifj4

如上範例,可以看到它印出 a 這個變數的記憶體位址

我用兩個範例跟大家說明,運用指標的差異

package main

import (
	"fmt"
)


func Compute(a int) {
	a = 0
}
func main() {
	x := 5
	Compute(x)
	fmt.Println(x)
}

https://play.golang.org/p/HtdbgipmdW2

上面範例經過 Compute 這個 func ,x 值並無改變,因為在 golang ,運作行為是『複製』 變數傳進去,所以兩個變數是完全獨立且分開的。

package main

import (
	"fmt"
)

func Compute(a *int) {
	*a = 0
}
func main() {
	x := 5
	Compute(&x)
	fmt.Println(x)
}

https://play.golang.org/p/X-lETZ5ifj4

上面範例為什麼 x,會有不一樣? 是因為這時侯 golang 行為是傳送位址進去,所以在 Compute 裡面所改到的值是原始 x,所改到的值。

golang 裡面 slice & map 都是 pointer型別,所如果把它當作參數傳入使用,要注意。

struct & func

在一般來說常見的 OOP (Object-oriented programming),有 class 也就會有所謂的 method,那在 golang 中要如何實現呢?

package main

import (
	"fmt"
)

type Member struct {
	Age  int
	Name string
}

func (m *Member) GetAge() int {
	return m.Age
}
func (m *Member) GetName() string {
	return m.Name
}

func main() {
	mem := &Member{
		Age:  18,
		Name: "syhlion",
	}
	fmt.Printf("Member Name:%s, Age:%d", mem.GetName(), mem.GetAge())
}

https://play.golang.org/p/NSqtIRbtY2l

由上面範例可以看到,只要在原本 func Name 之前加入,這個 func 要參照到哪,就可以像使用一些常見的 OOP ((Object-oriented programming)) 語言去設計所謂的 class。當然它也可以選擇運用,要不要使用 pointer,參照到 struct。

初學來說,如果還搞不清楚使用時機,建議都用 pointer 參照 struct。

golang 作者有特別聲明,golang 不是傳統的 OOP (Object-oriented programming),所以在設計上,可以運用一些 OOP (Object-oriented programming) 觀念,但不要硬要套用。 ref https://golang.org/doc/faq#Is_Go_an_object-oriented_language