iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
4
Software Development

Go繁不及備載系列 第 10

# Day10 繼續Go-基本組合型別2(map, struct)

Day10 繼續Go-基本組合型別2(map, struct)

映射 Map

【map】

map有很多種翻譯,名詞叫作地圖,動詞有映射對應對照的意思 ,在一些程式語言中則有Key-Value一個關鍵字對應一個值的用法。

var Variable = map[Type]Type{}

var a = map[int]string{}

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

可以像這樣bool對應到任何string

var Male = map[bool]string{
	true:  "公",
	false: "母",
}

或是設定string對應到int

var Number = map[string]int{
	"零": 0,
	"壹": 1,
	"貳": 2,
}
Number["參"] = 3

string對應到string也可以,

var Size = map[string]string{
	"big":    "大",
	"medium": "中",
	"small":  "小",
}

只要任兩種型態設定好、對應好之後就能用哩,

string的前後要加雙引號" ",來試試效果吧!

取map

fmt.Print(Male[true],Number["參"])
/* result:
公3
*/

【for 迭代遍歷】

透過for range關鍵字,遍歷造訪結構內的每個元素

for key, value := range Size {
	fmt.Println(key, value)
}
/* result:
big 大
medium 中
small 小
*/

結構 Struct

【struct】

結構裡面可以放多個變數(intstringslicemap等等)、物件、甚至是結構。
宣告結構Struct的幾種方式:

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

package main

import "fmt"

type Res struct {
	Status string     `json:"status"`
	Msg string        `json:"msg"`
}

func main()  {
	res1 := new(Res)

	var res2 = new(Res)

	var res3 *Res

	res4 := &Res{
		Status: "failed",
	}

	fmt.Println(res1, res2, res3, res4)
	fmt.Printf("%+v %+v %+v %+v",res1, res2, res3, res4)
}

/* result:
&{ } &{ } <nil> &{failed }
&{Status: Msg:} &{Status: Msg:} <nil> &{Status:failed Msg:}
*/

【Nested Structure】巢狀結構

結構中的結構的結構、大腸包小腸再包小小腸

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

type Wallet struct {
	Blue1000 int // 藍色小朋友
	Red100   int // 紅色國父
	Card     string
}

type PencilBox struct {
	Pencil string
	Pen    string
}

type Bag struct {
	Wallet    // 直接放入結構就好
	PencilBox // 直接放入結構就好
	Books     string
}

type Person struct {
	Bag
	Name string
}

func main() {
	var bag = Bag{
		Wallet{Card: "世華泰國信用無底洞卡", Red100: 5},
		PencilBox{Pen: "Cross", Pencil: "Pentel"},
		"Go繁不及備載", // Books
	}

	var Tommy = Person{}
	Tommy.Name = "Tommy"
	Tommy.Bag = bag

	fmt.Printf("%+v", Tommy)
}

/* result:
{Bag:{Wallet:{Blue1000:0 Red100:5 Card:世華泰國信用無底洞卡} PencilBox:{Pencil:Pentel Pen:Cross} Books:Go繁不及備載} Name:Tommy}
*/

藝涔 益晨 翊誠~ 的剝開我的Struct...


【指標、結構、位址】

這裡將上面的例子取一部分出來修改,

如果將main()裡的var Bag敘述改成 &Bag

type Person struct {
	Bag  // 放Bag這個物件
	Name string
}

func main() {
	var bag = &Bag{
		Wallet{Card: "世華泰國信用無底洞卡", Red100: 5},
		PencilBox{Pen: "Cross", Pencil: "Pentel"},
		"Go繁不及備載",
	}

	var Tommy = Person{}
	Tommy.Name = "Tommy"
	Tommy.Bag = *bag // 透過`取值`來取出bag位址裡面的東西

	fmt.Printf("%+v", Tommy)
}
/* result:
{Bag:{Wallet:{Blue1000:0 Red100:5 Card:世華泰國信用無底洞卡} PencilBox:{Pencil:Pentel Pen:Cross} Books:Go繁不及備載} Name:Tommy}
*/

印出bag 就要透過*來取值


如果將Person裡的Bag改成 *Bag

type Person struct {
	*Bag // 放指標
	Name string
}

func main() {
	var bag = &Bag{ // 指到位址
		Wallet{Card: "世華泰國信用無底洞卡", Red100: 5},
		PencilBox{Pen: "Cross", Pencil: "Pentel"},
		"Go繁不及備載",
	}

	var Tommy = Person{}
	Tommy.Name = "Tommy"
	Tommy.Bag = bag // 這裡就印出bag位址

	fmt.Printf("%+v", Tommy)
}
/* result:
{Bag:0xc000048050 Name:Tommy}
*/

這樣子就會印出bag的位址


雖然有點違反物理法則及常識,但

【小坑】如果Bag裡面有PencilBox,PencilBox裡面又有Bag

會怎麼樣呢?
答案是出現 invalid recursive type 的錯誤。

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

type PencilBox struct {
	Pencil string
	Pen    string
	Bag           // 你中有我 我中有你
}

type Bag struct {
	Wallet
	PencilBox
	Books     string
}

雖然放物件會出現錯誤,但是 放指針不會

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

type PencilBox struct {
	Pencil string
	Pen    string
	*Bag           // 你中有針
}

type Bag struct {
	Wallet
	PencilBox
	Books     string
}

func main() {
	var bag = Bag{
		Wallet{Card: "世華泰國信用無底洞卡", Red100: 5},
		PencilBox{Pen: "Cross", Pencil: "Pentel"},
		"Go繁不及備載",
	}
	bag.PencilBox.Bag = &bag // 包包裡放針

	fmt.Printf("%+v", *bag.PencilBox.Bag)
}

/* result:
{Wallet:{Blue1000:0 Red100:5 Card:世華泰國信用無底洞卡} PencilBox:{Pencil:Pentel Pen:Cross Bag:0xc000046060} Books:Go繁不及備載}
*/

上一篇
# Day09 Go繼續開車-基本組合型別(array, slice)
下一篇
# Day11 Go加油-韓式寒士函式(func)
系列文
Go繁不及備載35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言