package main import "fmt" type Student struct { Name string Age int Score float64 } // 将公有的方法绑定到Student 结构体 func (s *Student) GetInfo() { fmt.Printf("学生姓名=%v, 年龄=%v,成绩=%v \n", s.Name, s.Age, s.Score) } func (s *Student) SetScore(score float64) { s.Score = score } // 小学生 type Pupil struct { Student } // 这是pupil 结构体特有的方法 func (p *Pupil) Testing() { fmt.Printf("小学生正在考试中。。。。") } // 大学生 type Graduate struct { Student } // 这是 Graduate 结构体特有的方法 func (p *Graduate) Testing() { fmt.Printf("大学生正在考试中。。。。") } func main() { pupil := new(Pupil) pupil.Name = "gopher.cc" pupil.Age = 8 pupil.Testing() pupil.SetScore(70) pupil.GetInfo() graduate := new(Graduate) graduate.Name = "www.gopher.cc" graduate.Age = 23 graduate.Testing() graduate.SetScore(80) graduate.GetInfo() }
特殊说明
-
- 结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法都可以使用。
- 当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分。
package main import "fmt" type A struct { Name string } func (a *A) hello() { fmt.Println("A say hello!", a.Name) } type B struct { Name string A } func (b *B) hello() { fmt.Println("B say hello!", b.Name) } func main() { var b = new(B) b.Name = "gopher.cc" b.hello() // 就近访问 b.A.Name = "www.gopher.cc" // 指定赋值 b.A.hello() // 指定访问 }
- 结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须指定匿名结构体名字,否则编译报错。
package main import "fmt" type A struct { Name string age int } type B struct { Name string Score float64 } type C struct { A B //Name string } func main() { var c = new(C) c.A.Name = "gopher.cc" fmt.Println(c) }
- 如果一个struct 嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法是,必须带上结构体的名字。
package main import "fmt" type A struct { Name string } type B struct { a A } func main() { var b = new(B) b.a.Name = "gopher.cc" fmt.Println(b) }
- 嵌套匿名结构体后,也可以在创建结构体变量时,直接指定各个匿名结构体字段的值。
package main import "fmt" type Goods struct { Name string Price float64 } type Brand struct { Name string Address string } type TV struct { Goods Brand } func main() { tv := TV{ Goods: Goods{ Name: "夏普", Price: 500.0, }, Brand: Brand{ Name: "夏普", Address: "北京", }, } fmt.Println(tv) }
- 结构体的匿名字段可以是基本数据类型
package main import "fmt" type A struct { Name string } type B struct { A int } func main() { var b = new(B) b.Name = "gopher.cc" b.int = 10 fmt.Println(b.Name, b.int) }
说明:
1. 如果一个结构体有int类型的匿名字段,就不能再有第二个;
2. 如果需要有多个int的字段,则必须给int字段指定名字。