Go中方法接收器与switch xxx.(type) 的使用
switch xxx.(type) 是一种特殊的 switch 使用,用于判断实现了某一接口的变量的类型是什么。
首先上 Demo 代码
package main
import "fmt"
type interfaceA interface {
funcA() string
funcB() string
}
type structA struct {
MemberA string
MemberB string
}
type structB struct {
MemberA string
MemberB string
}
type structC struct {
MemberA string
MemberB string
}
var _ interfaceA = (*structA)(nil)
var _ interfaceA = (*structB)(nil)
func (sa *structA) funcA() string {
return sa.MemberA
}
func (sa *structA) funcB() string {
return sa.MemberB
}
func (sb structB) funcA() string {
return sb.MemberA
}
func (sb structB) funcB() string {
return sb.MemberB
}
func main() {
var testA interfaceA
// testA = structB{}
testA = &structA{}
// testA = structA{} //编译器会报错
testA = &structB{}
switch testA.(type) {
case *structA:
fmt.Println("im structA")
case structB:
fmt.Println("im structB")
case *structB:
fmt.Println("im structB ptr")
// case structC: // 编译器会报错,因为 structC 没有实现 interfaceA
// fmt.Println("im structC")
}
}
var _ interfaceA = (*structA)(nil)
var _ interfaceA = (*structB)(nil)
这里是两个约束, 确保结构体 structA 和结构体 structB 都已经完成了对接口 interfaceA 的实现。
// testA = structA{} //编译器会报错
这是因为实现了 structA 中的方法 funcA 和 funcB,他们的接收器中都为指针, 所以不能使用值。
这里又涉及了另一个知识点:
使用值时,只包含值方法集,不包含指针方法集
使用指针时,包含值方法集,也包含值方法集(就是全部都包括)
这就是为什么在上文demo中,可以使用 testA = structB{}
也可以使用 testA = &structB{}
。
因为 structB 中的方法,其接收器都为值。所以使用指针 &structB{}
时,可以直接调用方法 funcA 和 funcB
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。