結構體(struct)
go中沒有物件這一概念,所以採用了結構體的概念,結構體在go中有著非常重要的位置。結構體是值型別,所以可以使用new函式來建立。結構體中欄位必須唯一。
結構體定義如下:
type identifier struct {
filed type
filed type
}
複製程式碼
filed就是結構體的欄位名字,type是欄位的型別,如果暫時不知道命名,可以使用 _ 來進行佔位。欄位可以使用任何型別,甚至是結構體本身,也可以是函式或者介面。 一般來說,給結構體的欄位賦值這樣即可:
var s T
s.a = 1
s.b = 2
複製程式碼
使用new函式給一個新的結構體變數分配記憶體,返回已分配記憶體:
var t *T = new(T)
// or
t := new(T)
複製程式碼
例子:
type Person struct {
Name string
Age int
Sex int
}
func main() {
person := new(Person)
person.Name = "Tim"
person.Age = 10
person.Sex = 1
//or
person := &Person{"Tim", 10 , 1}
fmt.Println(person)
}
// 輸出 &{Tim, 10, 1}
複製程式碼
就像面嚮物件語言那樣,可以使用點來給欄位進行賦值,同樣的也可以通過點來進行獲取欄位的值。
結構體同樣可以作為引數進行傳遞:
func getPersonName(p *Person) string {
return p.Name
}
func main() {
...
fmt.Prinltn(getPersonName(person))
}
// 輸出 Tim
複製程式碼
如果想知道一個結構體佔用了多少記憶體,可以使用:
size := unsafe.Sizeof(T{}}
複製程式碼
結構體中除了欄位和型別外,還有一個可選的標籤,一個欄位的輔助字串,只有reflect能獲取它。
例子:
type Person struct {
Name string "Name"
Age int "Age"
Sex int "Sex"
}
func main() {
person := Person{}
person.Name = "Tim"
person.Age = 10
person.Sex = 1
for i := 0; i < 3; i++ {
refTag(person, i)
}
}
func refTag(p Person, i int) {
pType := reflect.TypeOf(p)
iFiled := pType.Filed(i)
fmt.Println(iFiled.Tag)
}
//out
複製程式碼
reflect.TypeOf可以獲取變數的正確型別,如果變數是一個結構體,就可以通過Filed來索引該結構體的欄位,然後就可以使用Tag屬性。
go結構體還支援一個特殊欄位,匿名欄位。這些欄位沒有顯式的名字,只有欄位型別,此時欄位型別也就是欄位的名字,匿名欄位也可以是一種結構體。
例子:
type Test1 struct {
t1 int
t2 int
}
type Test struct {
a int
b string
bool
Test1
}
func main() {
test := new(Test)
test.a = 1
test.b = "2"
test.bool = true
test.t1 = 2
test.t2 = 3
fmt.Println(test)
}
//out &{1, "2", true, 2, 3}
複製程式碼
通過test.bool的名字來獲取匿名欄位的資料,於是可以得出一個結論,在一個結構體中對於每一種資料型別只能有一個匿名欄位。 在結構體內嵌結構體是,如果遇到命名衝突但是又都需要保留時,可以使用:
Test.Test1.Filed
複製程式碼
這樣使用就避免了命名衝突。
方法
go方法是作用在接收者上的一個函式,接收者是某種型別的變數,因此方法是一種型別的函式。接收者型別幾乎可以任何型別,指標型別和函式型別就不行。 因為方法是函式,所以方法不能被過載,對於一個型別只有一個既定名稱的方法。 定義方法的格式如下:
func (r receiver_type) methodName(parmeter_list) (value_list){
...
}
複製程式碼
r是receiver_type的例項,methodName是r的方法名,呼叫也很簡單,r.methodName() 即可。 例子:
type Person struct {
Name string
Age int
}
func (p *Person) GetName() string {
return p.Name
}
func (p *Person) GetAge() int {
return p.Age
}
func main() {
p := new(Person)
p.Name = "1"
p.Age = 2
fmt.Prinltn(p.GetName())
fmt.Prinltn(p.GetAge())
}
// out "1" 2
複製程式碼
微信搜尋「goentry-xyz」,關注公眾號「燈下獨碼」