这是我参与更文挑战的第4天,活动详情查看: 更文挑战
结构体
定义与初始化
// 定义结构体
type structName struct{
fieldName typeName
fieldName2 typeName
...
}
复制代码
- 使用type + struct 声明一个结构体,结构体是一种类型
- 接口体内是字段,可以零个,一个或多个
//定义Person结构体
type Person struct {
name string
age int
}
// 初始化变量
var p Person // 默认零值的变量p
var p2 Person {"jasen",18} //初始化字段name=jasen,age=18的变量p
var p3 Person {age:18,name:"jasen"} // 有字段名称则可以无序
p4 := Person{"Tom",20}
复制代码
声明一个Person类型的结构体变量p,其中p中的字段都默认使用各字段的零值。
结构体的组合
type student struct{
name string
age int
}
type group struct {
name string
code int
student // 内嵌student结构体
}
复制代码
- 外部类型可以使用内部类型的字段和方法
- 若外部类型定义和内部类型相同的方法,外部类型会覆盖内部类型(方法的复写)
接口
接口定义和实现
接口是对某一类行为的规范和抽象。
//定义接口
type interfaceName interface{
method() result
}
// 接口定义与实现
type Caller interface{
sayHi() string
}
type person struct{
name string
}
// person类型实现接口
func (p *person)sayHi() string {
fmt.Println("实现了接口的p.name=",p.name)
return "ok"
}
复制代码
- 使用关键字type + interface 定义接口
- method()是接口内的方法,是接口的约定,具体怎么实现由具体的类型来决定
- 如果接口有多个方法,则某类型必须都实现每个方法
面向接口
// 以接口为函数的参数
func printResult(c Caller){
fmt.Println(sayHi())
}
//teacher也实现了Caller接口
type teacher struct{
name string
}
// person类型实现接口
func (t *teacher)sayHi() string {
fmt.Println("实现了接口的t.name=",t.name)
return "ok"
}
// 调用printResult函数
printResult(p) //输出结果:ok
printResult(t) //输出结果:ok
复制代码
值接收者和指针接收者
func (t teacher)sayHi() string {
fmt.Println("实现了接口的t.name=",t.name)
return "ok"
}
func (t *teacher)sayHi() string {
fmt.Println("实现了接口的t.name=",t.name)
return "ok"
}
复制代码
在方法绑定类型时,无论绑定值类型还是指针类型都是可以调用方法。但是,在实现接口的时候,两者是有区别的
- 值类型接收者:实现接口时,对应值类型和指针类型都实现了该接口
- 指针类型接收者:实现接口时,只有指针类型实现了该接口
继承和组合
Go语言中,没有继承概念,没有父子关系,但是可以通过组合的方式,达到代码复用。
type read interface{ ... }
type write interface{ ... }
// 组合read接口和write接口,readAwrite接口有其2个接口的所有方法
type readAwrite interface{
read
write
}
复制代码
类型断言
如果2个类型实现了同一个接口,那么就会有类型断言
// 上面例子person和teacher都实现了接口Caller
p1 := p.(person)
t1 := t.(teacher)
// 如果断言失败则程序会抛出错误,程序运行失败,所以go提供返回值,如下
// 通过ok标志来判断断言成功与否
p1,ok := p.(person)
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END