「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」。
0 环境
- 系统环境:win10
- 编辑器:vscode
- go版本:gol.17.3
- 参考文章:go语言中文文档
1 指针接收者
如下:指针类型 --> (u users),区别多了一个。
func (u *users) show() string{
}
指针接收案例。
type users struct {
id uint
usersName string
addr addr
}
type addr struct {
city string
}
type Stringser interface {
show() string
}
func (u *users) show() string {
fmt.Println("the usersname is -->",u.usersName," |id is -->",u.id)
return "ok"
}
func printStr(u Stringser) {
fmt.Println(u.show())
}
func structShow() {
u := users{usersName:"小明", id: 1, addr : addr{
city: "美国",
}}
printStr(u)
printStr(&u)
}
func main() {
structShow()
}
可以看出直接值类型传值,会报没有实现这个接口,也就是说这里的指针类型只对应&u。也就是说:接收者是值类型的话,类型本身还是指针类型都可以实现接口。但是接收者是指针类型,只能*类型(* users)才可以实现接口。
2 组合和继承
go语言中没有继承。现在学到的结构体和接口(是没有继承关系的),正常情况下:组合用的多,特点是可复用(灵活)。
组合的思想,在定义结构体的时候,就已经用上了,我定义了一个users的结构体,它的内部又加进去了一个结构体类型,这就是组合了。但是这样子,我们怎么区分它们呢,总不能说组合和被组合的结构体类型吧,组合了其他结构体的(xx {xx 其他结构体}),叫外部类型。被组合了的叫内部类型(外部类型 { 内部结构体 --> 内部类型})。说白了,{}左边的是外部类型,{}里面的是内部类型。
type users struct {
id uint
usersName string
addr addr
}
type addr struct {
city string
}
接口也是类似。
type a interface {
showa()
}
type b interface {
showb()
}
type c interface {
a
b
}
3 类型断言
查看我想知道哪些个接口已经被调用过了,用
接口变量. (接收者类型),注意:类型不能把括号省略哦。要用if else判断,若是只用if ok {}判断,当结果ok为false时,并且没有else判断,它会抛出异常,终止程序运行。
只是上面代码指针接收者里的代码,做了拓展,具体内容如下:
func (addr addr) show() string {
fmt.Println("the addr is -->",addr.city)
return "ok"
}
func printStr(u Stringser) {
a, ok := u.(addr)
if ok {
fmt.Println("addr -->",a)
} else {
fmt.Println("不是addr")
}
b, ok1 := u.(*users)
if ok1 {
fmt.Println("*users -->",b)
} else {
fmt.Println("不是*users")
}
fmt.Println(u.show())
}
4 总结
对于接收者类型是值类型时,它对于类型,一视同仁(不挑食的人)。而对于接收者类型是指针类型时,它比较挑剔,只认自己人(挑食的人)。有时候我们想知道挑食的那位或者不挑食的那位,今天是否吃了没(类型断言),注意加
()和判断语句里加else。对于组合来说,就有点套娃,在外面的那个娃叫外面类型,在里面的那个娃叫内部类型。