GO語言基礎知識(四)結構體和方法(不斷更新)

一、類型和結構體

基於已有類型(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等。


讓我們一起進步學習,共同成長;歡迎大家關注微信公眾號:芝麻技術棧


分享到:


相關文章: