1.结构体定义和变量可见性规则
2.结构体做参数传递
3.结构体方法(封装)
4.匿名字段(继承)
5.方法继承(多态)
6.接口的定义、继承
7.空接口类型
8.断言
一、结构体
结构体是一种聚合的数据类型,是一个对象多个属性的集合体。(个人暂时理解为一个类)
package main
import "fmt"
//定义一个结构体,其中有id,年龄,姓名,性别的属性
type Person struct {
Id int
Age int
Name string
sex string
}
func main() {
//声明一个Person类型的变量并赋值
p := Person{
Id: 1,
Age: 20,
Name: "google",
sex: "M",
}
//打印p的信息
fmt.Println(p)
}
打印结果为:{1 20 google M}
可见性规则:在结构体Person中,sex首字母为小写,其他均为大写。go语言是区分大小写的,首字母为大写的属性、方法其他包也可以调用,而小写的只能在包内调用。
二、结构体做参数传递
package main
import "fmt"
//定义一个结构体,其中有id,年龄,姓名,性别的属性
type Person struct {
Id int
Age int
Name string
sex string
}
func sayHello(p Person) {
fmt.Printf("%v say Hello Go!!!", p.Name)
}
func main() {
//声明一个Person类型的变量并赋值
p := Person{
Id: 1,
Age: 20,
Name: "google",
sex: "M",
}
sayHello(p)
}
添加sayHello方法,并传入参数p,程序会打印 google say Hello Go!!!。
三、结构体方法(封装)
将操作封装到方法内部,对外提供方法名,调用者只需要知道方法的用途,不用关心具体实现。
package main
import "fmt"
//定义一个结构体,其中有id,年龄,姓名,性别的属性
type Person struct {
Id int
Age int
Name string
sex string
}
//Person结构体方法
func (p Person) sayHello() {
fmt.Printf("%v say Hello Go!!!\n", p.Name)
}
//使用指针调用方法
func (p *Person) running() {
fmt.Printf("%v 正在拼命加载....\n", (*p).Name)
}
//对外提供修改名字的方法
func (p *Person) setName(s string) {
(*p).Name = s
}
func main() {
//声明一个Person类型的变量并赋值
p := Person{
Id: 1,
Age: 20,
Name: "google",
sex: "M",
}
p.sayHello()
p.running()
p.setName("baidu")
p.running()
}
程序打印结果为:
google say Hello Go!!!
google 正在拼命加载....
baidu 正在拼命加载....
对象调用结构体方法属于值传递,想改变结构体属性,需要用指针调用方法;
指针可以调用变量类型的方法,变量也可以调用指针类型的方法;
四、匿名字段(继承)
在子结构体中定义一个父结构体的匿名字段,则子结构体会继承父结构体所有的属性和方法。
package main
import "fmt"
//定义一个结构体,其中有id,年龄,姓名,性别的属性
type Person struct {
Id int
Age int
Name string
sex string
}
//Person结构体方法
func (p Person) sayHello() {
fmt.Printf("%v say Hello Go!!!\n", p.Name)
}
//使用指针调用方法
func (p *Person) running() {
fmt.Printf("%v 正在拼命加载....\n", (*p).Name)
}
//对外提供修改名字的方法
func (p *Person) setName(s string) {
(*p).Name = s
}
//定义一个Student结构体
type Student struct {
//使Student继承Person
Person
class string
}
//Student专属方法
func (s Student) Classing() {
fmt.Printf("%v 正在上 %v 课", s.Name, s.class)
}
func main() {
//声明一个Student类型的变量并给class属性赋值
s := Student{class: "Go语言"}
//Student继承Person的setName方法
s.setName("baidu")
s.running()
s.Classing()
}
Student继承Person,拥有它的全部属性和方法,所以打印结果为:
baidu 正在拼命加载....
baidu 正在上 Go语言 课
五、方法继承(多态)
子结构体拥有和父结构体同样的方法,则子结构体会重写父结构体的方法。
package main
import "fmt"
//定义一个结构体,其中有id,年龄,姓名,性别的属性
type Person struct {
Id int
Age int
Name string
sex string
}
//Person结构体方法
func (p Person) sayHello() {
fmt.Printf("%v say Hello Go!!!\n", p.Name)
}
//使用指针调用方法
func (p *Person) running() {
fmt.Printf("%v 正在拼命加载....\n", (*p).Name)
}
//对外提供修改名字的方法
func (p *Person) setName(s string) {
(*p).Name = s
}
//定义一个Student结构体
type Student struct {
//使Student继承Person
Person
class string
}
//Student专属方法
func (s Student) Classing() {
fmt.Printf("%v 正在上 %v 课\n", s.Name, s.class)
}
func (s Student) running() {
fmt.Printf("%v 正在努力学习...\n", s.Name)
}
func main() {
//声明一个Student类型的变量并给class属性赋值
s := Student{class: "Go语言"}
//Student继承Person的setName方法
s.setName("baidu")
s.running()
s.Classing()
}
Student中重写了running方法,打印结果为:
baidu 正在努力学习...
baidu 正在上 Go语言 课
六、接口的定义、继承
package main
import "fmt"
//定义一个Testinter接口
type Testinter interface {
sayHello(s string)
}
type Person struct {
Name string
}
//Person实现了Testinter接口的sayHello方法
func (p Person) sayHello(s string) {
fmt.Printf("%v say %v\n", p.Name, s)
}
func main() {
var t Testinter
t = Person{"google"}
t.sayHello("Hello Go")
}
Person为接口Testinter的实现,打印结果为:google say Hello Go
package main
import "fmt"
//定义一个Testinter接口
type Testinter interface {
sayHello(s string)
}
type SingInter interface {
Testinter
sing(s string)
}
type Person struct {
Name string
}
//Person实现了Testinter接口的sayHello方法
func (p Person) sayHello(s string) {
fmt.Printf("%v say %v\n", p.Name, s)
}
func (p Person) sing(s string) {
fmt.Printf("%v sing %v\n", p.Name, s)
}
func main() {
var t SingInter
t = Person{"google"}
t.sayHello("Hello Go")
t.sing("纸短情长")
}SingInter接口继承了TestInter接口,Person为SingInter的实现,可以调用sayHello和sing两个方法。
七、空接口类型
package main
import "fmt"
func main() {
m := make(map[int]interface{})
m[0] = "Go"
m[1] = 'm'
m[2] = 6
m[3] = true
for key, value := range m {
fmt.Printf("m[%d] = %v \n", key, value)
}
}定义一个map,键为int型,值为空接口类型。空接口类型可以匹配任何类型。
八、断言
使用switch实现类型断言
package main
import "fmt"
func main() {
m := make(map[int]interface{})
m[0] = "Go"
m[1] = 6
m[2] = true
for key, value := range m {
switch data := value.(type) {
case int:
fmt.Printf("m[%d] = %d \n", key, data)
case string:
fmt.Printf("m[%d] = %s \n", key, data)
case bool:
fmt.Printf("m[%d] = %v \n", key, data)
}
}
}