go支持只提供類型而不寫字段名的方式,也就是匿名字段,也稱爲嵌入字段編程
//package 聲明開頭表示代碼所屬包 package main import "fmt" //定義人的結構體 type Person struct { name string sex string age int } //學生 type Student struct { //匿名字段 //默認Student包含了Person全部字段 Person id int addr string } func main() { s2 := Student{Person:Person{"約漢","female",10},id:2} fmt.Println(s2) } //{{約漢 female 10} 2 }
同名字段的狀況函數
//package 聲明開頭表示代碼所屬包 package main import "fmt" //定義人的結構體 type Person struct { name string sex string age int } //學生 type Student struct { //匿名字段 //默認Student包含了Person全部字段 Person id int addr string //同名字段 name string } func main() { var s Student //就近賦值 s.name = "約漢" fmt.Println(s) //若給外面賦值 s.Person.name = "接客" fmt.Println(s) } //{{ 0} 0 約漢} //{{接客 0} 0 約漢}
全部的內置類型和自定義類型都是能夠做爲匿名字段去使用測試
package main import "fmt" //定義人的結構體 type Person struct { name string sex string age int } //自定義類型 type mystr string //學生 type Student struct { //匿名字段 //默認Student包含了Person全部字段 Person //內置 int mystr } func main() { //初始化 s1 := Student{Person{"約漢","male",18},1,"bj"} fmt.Println(s1) fmt.Println(s1.name) }
指針類型匿名字段設計
//package 聲明開頭表示代碼所屬包 package main import "fmt" //定義人的結構體 type Person struct { name string sex string age int } //學生 type Student struct { //匿名字段 //默認Student包含了Person全部字段 *Person //內置 id int addr string } func main() { s1 := Student{&Person{"約漢","male",18},1,"bj"} fmt.Println(s1) fmt.Println(s1.name) } //{0xc0420661e0 1 bj} //約漢
基礎類型指針
//package 聲明開頭表示代碼所屬包 package main import "fmt" //任務:定義方法實現2個數相加 type MyInt int //傳統定義方式,面向過程 func Add(a, b MyInt) MyInt { return a + b } //面向對象 func (a MyInt) Add(b MyInt) MyInt { return a + b } func main() { var a MyInt = 1 var b MyInt = 1 fmt.Println("Add(a,b)=", Add(a, b)) //調用面向對象的方法 fmt.Println("a.Add(b)=",a.Add(b)) } //Add(a,b)= 2 //a.Add(b)= 2
結構體類型code
//package 聲明開頭表示代碼所屬包 package main import "fmt" type Person struct { name string sex string age int } //爲Person添加方法 func (p Person) PrintInfo() { fmt.Println(p.name, p.sex, p.age) } func main() { p := Person{"接客", "male", 18} p.PrintInfo() }
值語義和引用語義對象
//package 聲明開頭表示代碼所屬包 package main import "fmt" type Person struct { name string sex string age int } //設置指針做爲接收者的方法,引用語義 func (p *Person) SetInfoPointer() { (*p).name = "接客" p.sex = "female" p.age = 22 } //值做爲接收者,值語義 func (p Person) SetInfoValue() { p.name = "約漢" p.sex = "male" p.age = 20 } func main() { //指針做爲接收者的效果 p1 := Person{"擼死", "male", 19} fmt.Println("函數調用前=", p1) (&p1).SetInfoPointer() fmt.Println("函數調用後=", p1) fmt.Println("================寂寞的分割線=================") //值做爲接收者的效果 p2 := Person{"約漢", "male", 18} fmt.Println("函數調用前=", p2) p2.SetInfoValue() fmt.Println("函數調用後=", p2) } //函數調用前= {擼死 male 19} //函數調用後= {接客 female 22} //================寂寞的分割線================= //函數調用前= {約漢 male 18} //函數調用後= {約漢 male 18}
方法的繼承繼承
package main import "fmt" type Person struct { name string sex string age int } //爲Person定義方法 func (p *Person) PrintInfo() { fmt.Printf("%s,%s,%d\n",p.name,p.sex,p.age) } type Student struct { Person id int addr string } func main() { p :=Person{"接客","male",18} p.PrintInfo() //學生也去調,方法繼承 s := Student{Person{"接客","male",18},2,"bj"} s.PrintInfo() }
方法的重寫接口
package main import "fmt" type Person struct { name string sex string age int } //爲Person定義方法 func (p *Person) PrintInfo() { fmt.Printf("%s,%s,%d\n", p.name, p.sex, p.age) } type Student struct { Person id int addr string } //Student定義方法,實際上就至關於方法重寫 func (s *Student) PrintInfo() { fmt.Printf("Student:%s,%s,%d\n", s.name, s.sex, s.age) } func main() { p := Person{"接客", "male", 18} p.PrintInfo() //學生也去調,方法繼承 s := Student{Person{"接客", "male", 18}, 2, "bj"} s.PrintInfo() //顯式調用 s.Person.PrintInfo() }
方法值和方法表達式
package main import "fmt" type Person struct { name string sex string age int } func (p *Person) PrintInfoPointer() { //%p是地址,%v是值 fmt.Printf("%p,%v\n", p, p) } func main() { p := Person{"接客", "male", 18} //傳統的調用方法的方式 p.PrintInfoPointer() //使用go方法值特性調用 pFunc1 := p.PrintInfoPointer pFunc1() //使用go方法表達式調用 pFunc2 := (*Person).PrintInfoPointer pFunc2(&p) }
練習:建立屬性的getter和setter方法並進行調用
package main import "fmt" type Dog struct { name string //1公 0母 sex int } //封裝dog的方法 //setter func (d *Dog) SetName(name string) { d.name = name } //getter func (d *Dog) GetName() string { return d.name } //咬人 func (d *Dog) bite() { fmt.Printf("讓本汪%s 來給你上課...", d.name) } func main() { d := Dog{"二哈", 1} d.bite() }
接口定義與實現
package main import "fmt" //定義人的接口 type Humaner interface { //說話 Say() } //學生結構體 type Student struct { name string score int } //Student實現Say()方法 func (s *Student) Say() { fmt.Printf("Student[%s,%d] 瞌睡不斷\n", s.name, s.score) } type Teacher struct { name string group string } //老師實現接口 func (t *Teacher) Say() { fmt.Printf("Teacher[%s,%s] 毀人不倦\n", t.name, t.group) } //自定義類型 type MyStr string //自定義類型實現方法 func (str MyStr) Say() { fmt.Printf("MyStr[%s] 同志醒醒,還有個bug\n", str) } func WhoSay(i Humaner) { i.Say() } func main() { s := &Student{"約漢", 88} t := &Teacher{"擼死", "Go語言"} var tmp MyStr = "接客" s.Say() t.Say() tmp.Say() //go的多態,調用同一個接口,不一樣表現 WhoSay(s) WhoSay(t) WhoSay(tmp) //make()建立 x := make([]Humaner, 3) x[0], x[1], x[2] = s, t, tmp for _, value := range x { value.Say() } }
接口繼承
package main import "fmt" //定義人的接口 type Humaner interface { //說話 Say() } type Personer interface { //等價於寫了Say() Humaner Sing(lyrics string) } //學生結構體 type Student struct { name string score int } //Student實現Say()方法 func (s *Student) Say() { fmt.Printf("Student[%s,%d] 瞌睡不斷\n", s.name, s.score) } func (s *Student) Sing(lyrics string) { fmt.Printf("Student sing[%s]!!\n", lyrics) } func main() { s := &Student{"約漢", 88} var p Personer p = s p.Say() p.Sing("互擼娃") }
comma-ok斷言
package main import "fmt" //空接口 type Element interface{} type Person struct { name string age int } func main() { //切片 list := make([]Element, 3) //int list[0] = 1 list[1] = "Hello" list[2] = Person{"luhan", 18} //遍歷 for index, element := range list { //類型斷言:value ,ok = element.(T) //value 是變量的值,ok是返回的布爾值,element是接口變量,T是斷言類型 if value, ok := element.(int); ok { fmt.Printf("list[%d]是int類型,值是%d\n", index, value) } else if value, ok := element.(int); ok { fmt.Printf("list[%d]是int類型,值是%d\n", index, value) } else if value, ok := element.(Person); ok { fmt.Printf("list[%d]是Person類型,值是[%s,%d]\n", index, value.name, value.age) } else { fmt.Printf("list[%d]是其餘類型\n", index) } } }
switch測試
package main import "fmt" //空接口 type Element interface{} type Person struct { name string age int } func main() { //切片 list := make([]Element, 3) //int list[0] = 1 list[1] = "Hello" list[2] = Person{"luhan", 18} //遍歷 for index, element := range list { switch value := element.(type) { case int: fmt.Printf("list[%d]是int類型,值是%d\n", index, value) case string: fmt.Printf("list[%d]是string類型,值是%s\n", index, value) default: fmt.Printf("list[%d]是其餘類型\n", index) } } }