一、類型和結構體
基於已有類型(string)定義的類型
具有原類型(string)的特性,並且可以擴展自己想要的特性
<code>type myString string/<code>
為類型(string)定義別名
新和原有在使用上完全一樣,但是在編譯後運行時,別名將不存在,進而替換成原類型名
<code>type aliasString = string
//比如下面之前遇到的
type byte = uint8
type rune = int32/<code>
自定義新的結構體,語法如下
type myType struct {
fieldName fieldType
fieldName fieldType
...
}
<code>//舉例type student struct {
name string
class string
age int
score int
}
//相同類型可以簡寫如下,和函數的多參數類型一樣可簡寫
type student1 struct {
name,class string
age,score int
}
//結構體對應的構造函數用來初始化結構體
//本質就是普通的函數,只不過約定成俗叫構造函數
func newStudent(name,class string,age int)*student {
return &student{
name: name,
class: class,
age: age,
}
}/<code>
- 結構體的實例化1,結構體佔用一塊連續的內存(先記憶著)
<code>var stu student
stu.name="student name"
stu.age=18/<code>
- 結構體的實例化2,可以使用鍵值對選擇初始化自己需要的字段
<code>stu1 := student{
name: "name",
class: "class",
age: 18, score: 100,}/<code>
- 結構體的實例化3,按列表方式初始化,這種方式需要初始化全部字段
<code>stu2 := student{"name","class",18,100}
//直接初始化結構體拿到對應的指針
stu3 := &student{"name","class",18,100}/<code>
- 結構體的實例化4,通過構造函數
<code>stu4 := newStudent("name","class",18)/<code>
結構體的匿名字段,同種類型的字段只允許有一個,侷限性很大
<code>type student2 struct {
string
int
}
var stu5 student2
stu5.string="string"
stu5.int=19/<code>
匿名結構體一般用在臨時場景
<code>teacher := struct {
name string
age int
}{
//聲明匿名結構體的同時進行初始化
name:"name",
age : 19,
}
//也可以按需更改字段的值
teacher.age=35/<code>
嵌套結構體的使用介紹
<code>type student struct {
name string
class string
age int
score int}
type collegeStudent struct {
major string
gfName string
stu student
}/<code>
<code>college := collegeStudent{
major: "major",
gfName: "gfName",
stu: student{
name: "name",
class: "class",
age: 28,
score: 90,
},
}
fmt.Println(college.gfName,college.stu.name)//gfName name/<code>
嵌套匿名結構體的使用場景
<code>type student struct {
name string
class string
age int
score int
}
type collegeStu struct {
major string
gfName string
student//注意沒有給student起變量名
}/<code>
<code>college1 := collegeStu{
major: "major",
student: student{
name: "name",
}
,}
fmt.Println(college1.major)//這個毋庸置疑
//對於匿名結構體的取值,直接使用其類型名作為變量名
fmt.Println(college1.student.name)
//上面可以簡寫成這樣
fmt.Println(college1.name)/<code>
總結:結構體的字段取值順序,先在結構體本身找,如果本身沒有這個字段,就去其嵌套的匿名結構體中找。在GO語言中是沒有繼承這個概念,而是叫做組合,通過組合匿名結構體來實現繼承。
二、結構體的方法
構造體的方法簡單介紹,格式如下
func (r receiveType)methodName(param paramType){
methodBody......
}
<code>func (s student)getSuffixName(suffix string)string{
return s.name + suffix
}/<code>
<code>fmt.Println(student{name: "小明", }.getSuffixName("好")) //小明好/<code>
修改接收者的值以及接收者copy副本代價較大時需用用指針接收者
<code>func (s *student)addAge(add int){
s.age += add
}/<code>
<code>s := student{ age: 18, }
s.addAge(1)
fmt.Println(s.age)/<code>
在GO語言中,不僅僅是結構體,可以為任意類型添加方法,當然指的本地類型,不是別人定義的包。
三、結構體的tag標籤
結構體的tag標籤的簡單介紹
type myType struct {
fieldName fieldType `tagName:"tagValue"`
fieldName fieldType `tagName:"tagValue"`
...
}
<code>bytes, err := json.Marshal(struct { major string
gfName string}{"major", "gfName"})if ok==nil { fmt.Println(string(bytes)) //因為collegeStu字段都是小寫代表私有,所以輸出的結果是{}/<code>
結構體字段的可見性,如果字段是小寫開頭,則表示只能在本地包中訪問,如果是大寫,則表示可以公開訪問(public),下面的這個字段大寫,可以得到正常的json數據。
<code>bytes, err := json.Marshal(struct {
Major string
GfName string
}{"Major", "GfName"})
if err==nil{
fmt.Println(string(bytes))
}else{
fmt.Println(err)}
//{"Major":"Major","GfName":"GfName"}/<code>
可以看到得到的json串,很不正規(開頭大寫),這個時候tag就上場了,可以通過tag標籤為json串的字段指定別名如下:
<code>bytes, err = json.Marshal(struct {
Major string `json:"major"`
GfName string `json:"gf_name"`}
{"Major", "GfName"})
if err==nil{
fmt.Println(string(bytes))
}else{
fmt.Println(err)
}
//{"major":"Major","gf_name":"GfName"}/<code>
同樣的類似於的tag還有db form binding等。
讓我們一起進步學習,共同成長;歡迎大家關注微信公眾號:芝麻技術棧
閱讀更多 芝麻技術棧 的文章
關鍵字: Go語言