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) } } }