golang學習筆記 struct 2

2022-04-11 07:02:04 字數 3940 閱讀 5170

go語言中,也和c或者其他語言一樣,我們可以宣告新的型別,作為其它型別的屬性或字段的容器。例如,我們可以建立乙個自定義型別person代表乙個人的實體。這個實體擁有屬性:姓名和年齡。這樣的型別我們稱之struct。如下**所示:

type person struct 

看到了嗎?宣告乙個struct如此簡單,上面的型別包含有兩個字段

如何使用struct呢?請看下面的**

type person struct 

var p person // p現在就是person型別的變數了

p.name = "astaxie" // 賦值"astaxie"給p的name屬性.

p.age = 25 // 賦值"25"給變數p的age屬性

fmt.printf("the person's name is %s", p.name) // 訪問p的name屬性.

除了上面這種p的宣告使用之外,還有另外幾種宣告使用方式:

下面我們看乙個完整的使用struct的例子

import "fmt"

// 宣告乙個新的型別

type person struct

// 比較兩個人的年齡,返回年齡大的那個人,並且返回年齡差

// struct也是傳值的

func older(p1, p2 person) (person, int)

return p2, p2.age-p1.age

}func main()

// 按照struct定義順序初始化值

paul := person

tb_older, tb_diff := older(tom, bob)

tp_older, tp_diff := older(tom, paul)

bp_older, bp_diff := older(bob, paul)

fmt.printf("of %s and %s, %s is older by %d years\n",

tom.name, bob.name, tb_older.name, tb_diff)

fmt.printf("of %s and %s, %s is older by %d years\n",

tom.name, paul.name, tp_older.name, tp_diff)

fmt.printf("of %s and %s, %s is older by %d years\n",

bob.name, paul.name, bp_older.name, bp_diff)

}我們上面介紹了如何定義乙個struct,定義的時候是欄位名與其型別一一對應,實際上go支援只提供型別,而不寫欄位名的方式,也就是匿名字段,也稱為嵌入字段。

當匿名欄位是乙個struct的時候,那麼這個struct所擁有的全部欄位都被隱式地引入了當前定義的這個struct。

讓我們來看乙個例子,讓上面說的這些更具體化

package main

import "fmt"

type human struct

type student struct

func main() , "computer science"}

// 我們訪問相應的字段

fmt.println("his name is ", mark.name)

fmt.println("his age is ", mark.age)

fmt.println("his weight is ", mark.weight)

fmt.println("his speciality is ", mark.speciality)

// 修改對應的備註資訊

mark.speciality = "ai"

fmt.println("mark changed his speciality")

fmt.println("his speciality is ", mark.speciality)

// 修改他的年齡資訊

fmt.println("mark become old")

mark.age = 46

fmt.println("his age is", mark.age)

// 修改他的體重資訊

fmt.println("mark is not an athlet anymore")

mark.weight += 60

fmt.println("his weight is", mark.weight)

}

圖例如下:

圖2.7 struct組合,student組合了human struct和string基本型別

我們看到student訪問屬性age和name的時候,就像訪問自己所有用的字段一樣,對,匿名字段就是這樣,能夠實現欄位的繼承。是不是很酷啊?還有比這個更酷的呢,那就是student還能訪問human這個字段作為欄位名。請看下面的**,是不是更酷了。

mark.human = human

mark.human.age -= 1

通過匿名訪問和修改字段相當的有用,但是不僅僅是struct欄位哦,所有的內建型別和自定義型別都是可以作為匿名欄位的。請看下面的例子

package main

import "fmt"

type skills string

type human struct

type student struct

func main() , speciality:"biology"}

// 現在我們來訪問相應的字段

fmt.println("her name is ", jane.name)

fmt.println("her age is ", jane.age)

fmt.println("her weight is ", jane.weight)

fmt.println("her speciality is ", jane.speciality)

// 我們來修改他的skill技能字段

jane.skills = string

fmt.println("her skills are ", jane.skills)

fmt.println("she acquired two new ones ")

fmt.println("her skills now are ", jane.skills)

// 修改匿名內建型別字段

jane.int = 3

fmt.println("her preferred number is", jane.int)

}

這裡有乙個問題:如果human裡面有乙個字段叫做phone,而student也有乙個字段叫做phone,那麼該怎麼辦呢?

go裡面很簡單的解決了這個問題,最外層的優先訪問,也就是當你通過student.phone訪問的時候,是訪問student裡面的字段,而不是human裡面的字段。

這樣就允許我們去過載通過匿名字段繼承的一些字段,當然如果我們想訪問過載後對應匿名型別裡面的字段,可以通過匿名欄位名來訪問。請看下面的例子

package main

import "fmt"

type human struct

type employee struct

func main() , "designer", "333-222"}

fmt.println("bob's work phone is:", bob.phone)

// 如果我們要訪問human的phone欄位

fmt.println("bob's personal phone is:", bob.human.phone)

}

Golang學習筆記

如果乙個method的receiver是 t,你可以在乙個t型別的例項變數v上面呼叫這個method,而不需要 v去呼叫這個method 即不需要 v method 如果乙個method的receiver是t,你可以在乙個 t型別的變數p上呼叫這個method,而不需要 p去呼叫這個method。i...

golang學習筆記

與c語法不同之處 1.引數列表中各個引數型別相同時可以只寫出最後乙個,如 add x,y int int 2.型別在引數名 變數 函式 後面 3.函式的左大括號要跟函式名同一行,否則編譯不過 4.函式定義要先寫關鍵字func在函式開頭 函式外的每個語句都要以func var等等關鍵字開頭 5.在包或...

Golang學習筆記

package main import fmt func main break default func inte ce select case defer gomap struct chan else goto package switch const fallthrough ifrange ty...