Struct 變數

Golang 基礎: Struct 變數

structs 是在 GO 中的一種資料型態,它就類似 JavaScript 中的物件(Object)或是 Ruby 中的 Hash

格式

type <結構名稱> struct {
    <鍵值1> <數值類型>
    <鍵值2> <數值類型>
}

建立 Struct

// STEP 1:建立一個 person 型別,它本質上是 struct
type Person struct {
    firstName string
    lastName  string
}

// 等同於
type Person struct {
  firstName, lastName string
}

根據資料輸入的順序決定誰是 firstName 和 lastName

alex := Person{"Alex", "Anderson"}
// {Alex Anderson}
fmt.Println(alex)
// {firstName:Alex lastName:Anderson}
fmt.Printf("%+v\n", alex)

直接取得 struct 的 pointer

alex := &Person{"Alex", "Anderson"}
// &{Alex Anderson}
fmt.Println(alex)
// &{firstName:Alex lastName:Anderson}
fmt.Printf("%+v\n", alex)

指定 structure 鍵值數值(建議使用)

程式可讀性高,不會指定到錯誤的鍵值資料

alex := Person{
   firstName: "Alex",
   lastName:  "Anderson",
}
// {Alex Anderson}
fmt.Println(alex)
// {firstName:Alex lastName:Anderson}
fmt.Printf("%+v\n", alex)

先宣告再賦值

var alex Person
alex.firstName = "Alex"
alex.lastName = "Anderson"
// {Alex Anderson}
fmt.Println(alex)

巢狀 struct

package main

import "fmt"

// STEP 1:定義外層 struct
type Person struct {
	firstName string
	lastName  string
	contact   ContactInfo
}

// STEP 2:定義內層 struct
type ContactInfo struct {
	email string
	phone string
}

func main() {
	// STEP 3:建立變數
	KayJayPerson := Person{
		firstName: "Kay",
		lastName:  "Jay",
		contact: ContactInfo{
			email: "kay@jay.com",
			phone: "0900000000",
		},
	}

	AlexPerson := Person{
		firstName: "Alex",
		lastName:  "Bob",
	}

	// {firstName:Kay lastName:Jay contact:{email:kay@jay.com phone:0900000000}}
	// STEP 4:印出變數
	fmt.Printf("%+v\n", KayJayPerson)

	// {firstName:Alex lastName:Bob contact:{email: phone:}}
	fmt.Printf("%+v\n", AlexPerson)
}

在 struct 使用 interface

package main

import "fmt"

type Salaried interface {
	getSalary() int
}

type Salary struct {
	basic     int
	insurance int
	allowance int
}

func (s Salary) getSalary() int {
	return s.basic + s.insurance + s.allowance
}

type Employee struct {
	firstName, lastName string
	salary              Salaried // 只要 salary 實作了 Salaried,就可以 Salaried interface type
}

func main() {
	ross := Employee{
		firstName: "Kay",
		lastName:  "Jay",
		// 因為 Salary struct 已經實作了 Salaried,因此可以當作 salary 的欄位值
		salary: Salary{
			basic:     1000,
			insurance: 100,
			allowance: 50,
		},
	}

  // Kay's salary is 1150
	fmt.Println("Kay's salary is", ross.salary.getSalary())
}

匿名 struct

employee := struct {
	Name string
}{
	Name: "KJ",
}
// {KJ}
fmt.Println(employee)
// {Name:KJ}
fmt.Printf("%+v\n", employee)

struct 的比較

當兩個 struct 結構相同,數值相同,可以拿來做比較

package main

import "fmt"

type Person struct {
	FirstName string
	LastName  string
}

func main() {
	Person1 := Person{
		FirstName: "Kay",
		LastName:  "Jay",
	}

	Person2 := Person{
		FirstName: "Kay",
		LastName:  "Jay",
	}

	// true
	fmt.Println(Person1 == Person2)
}

直接定義使用 struct 函式

package main

import (
	"fmt"
)

type People struct {
	name string
	age  int
}

func (people People) Hello(other People) string {
	return `Hi! ` + other.name + `, I am ` + people.name
}

func main() {
	KayPeople := People{name: `Kay`}
	JayPeople := People{`Jay`, 18}

	// Hi! Kay, I am Jay
	fmt.Println(JayPeople.Hello(KayPeople))
	// Hi! Jay, I am Kay
	fmt.Println(KayPeople.Hello(JayPeople))
}

func 前面有寫這個是 (people People) 結構的函式,所以 go 會直接將這個函式與 People struct 直接綁定再一起

所以建立完 struct 變數即可直接呼叫這個 Hello 函數

參考資料