Go(6) - type, struct

C 語言沒有 class,一般為了在 C 裡面實現類似 class 的功能會在 struct 掛上很多 function pointer。

Go 語言很像 C 語言,有 pointer 及 struct 但沒有 class。宣告 struct 時可以把 function 附加上去。

1. type:

type 可以用於建立一個新的型別或是建立型別的別名。

利用 "type 別名 = 型別" 可以建立型別的別名,使用得當可以增加程式的可讀性。

type myInt = int

func main() {
    var a myInt = 10
    fmt.Printf("Type of a is: %T\n", a) // Type of a is: int
}

利用 "type 新型別 型別" 可以建立新型別,這是 struct 的基礎。

type newInt int

func main() {
    var a newInt = 10
    fmt.Printf("Type of a is: %T\n", a) // Type of a is: main.newInt
}

2. struct:

上面利用 type 建立一個新的型別,我們可以把某種 struct 當成一種新的型別並定義一個名稱。

建立 Dog 型別,它是一種具有 name 和 int 的 struct。

type Dog struct {
    Name string
    Age  int
}

func main() {
    d := Dog{"White", 10} // 初始化
    fmt.Println(d.Name)
    fmt.Println(d.Age)
    fmt.Printf("Type of d is: %T\n", d) // Type of d is: main.Dog
}

3. 幫 struct 添加 function:

我們可以幫 struct 添加 function,讓它更像 class。

幫 Dog 添加 Bark(),需要注意的是 d 是一個新拷貝出來的物件 (晚點我們會證明)。

type Dog struct {
    Name string
    Age  int
}

func (d Dog) Bark() { // 拷貝建立 d 再呼叫 Bark()
    fmt.Println("Bark bark!")
}

func main() {
    d := Dog{"White", 10}
    d.Bark()
}

4. 使用 pointer 傳遞 instance:

我們想新增一個 Grow() 並希望它能幫 Dog 增加年紀。

type Dog struct {
    Name string
    Age  int
}

func (d Dog) Grow() {
    d.Age += 1
}

func main() {
    d := Dog{"White", 10}
    d.Grow()
    fmt.Println(d.Age) // 10
}

!! 注意 !! 上面的 d 在 Grow 後歲數並沒有增加,原因是因為呼叫 Grow() 的對象是新拷貝出來的 Dog。

我們利用 Dog 的 pointer 呼叫 Grow(),d.Age += 1 的對象是由傳入的 pointer 決定。

type Dog struct {
    Name string
    Age  int
}

func (d *Dog) Grow() {
    fmt.Printf("Address (Grow): %p\n", d)
    d.Age += 1
}

func main() {
    d := Dog{"White", 10}
    fmt.Printf("Address (main): %p\n", &d)
    d.Grow()
    fmt.Println(d.Age) // 11
}

不論你要不要修改 struct 的資料都應該使用 pointer 傳遞 instance,因為使用 pointer 可以免去不必要的拷貝。


留言

熱門文章