http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=22312037&id=3756923
一、struct
Go語言中,也有struct,定義與C語言類似,舉例說明如下:
type person struct {
name string
age int
}
上面就聲明了一個結構體person,包含兩個字段。可以如下來使用這個struct:
var P person //P現在就是person類型的變量了
P.name = "shicq" //賦值給P的name屬性
P.age = 31 //賦值給P的age屬性
fmt.Printf("The person's name is %s", P.name) //訪問P的name屬性
除了上面這種P的聲明使用之外,還有兩種聲明使用方式:
(1)按照順序提供初始化值。
P := person("Li Lei", 25)
(2)通過field:value的方式初始化,這樣可以任意順序。
P := person(age:24, name:"Han Meimei")
二、匿名字段
前文介紹了如何定義一個struct,定義的時候是字段名與其類型一一對應,實際上Go語言支持只提供類型,而不寫字段名的方式,也就是匿名字段,或稱為嵌入字段。當匿名字段是一個struct的時候,那么這個struct所擁有的全部字段都被隱式地引入了當前定義的這個struct。下面舉例說明之:
type Human struct {
name string
age int
}
type Student struct {
Human //匿名字段,那么默認Student就包含了Human的所有字段
speciality string
}
//初始化Student
mark := Student(Human{"shicq", 31}, "Computer Science")
//訪問相應字段
fmt.Println("His name is ", mark.name)
fmt.Println("His age is ", mark.age)
fmt.Println("His speciality is ", mark.speciality)
我們看到Student訪問屬性age和name的時候,就像訪問自己所擁有的字段一樣。當然Student也能通過訪問Human來訪問這兩個字段:
mark.Human = Human{"shicq", 31}
mark.Human.age -= 1
不僅僅是struct字段,所有內置類型和自定義類型都可以作為匿名字段,比如slice。
如果human中有一個叫做phone的字段,而student也有一個叫做phone的字段,該當如何呢?
Go語言中最外層的優先訪問,也就是當通過student.phone訪問的時候,訪問的是student里面的字段,而不是human里面的字段。
這就允許我們可以重載通過匿名字段繼承的一些字段,當然如果想訪問重載后對應的匿名類型里的字段,可以通過匿名字段名來訪問:
type Human struct {
name string
age int
phone string //Human類型擁有的字段
}
type Employee struct {
Human //匿名字段Human
speciality string
phone string //雇員的phone字段
}
Bob := Employee{Human{"Bob", 24, "777-444-xxxx"}, "Designer", "333-222"}
fmt.Println("Bob's work phone is ", Bob.phone)
fmt.Println("Bob's personal phone is ", Bob.Human.phone) //訪問Human的phone字段
package main
import (
"fmt"
"reflect" // 這里引入reflect模塊
)
type User struct {
Name string "user name" //這引號里面的就是tag
Passwd string "user passsword"
}
func main() {
user := &User{"chronos", "pass"}
s := reflect.TypeOf(user).Elem() //通過反射獲取type定義
for i := 0; i < s.NumField(); i++ {
fmt.Println(s.Field(i).Tag) //將tag輸出出來
}
}