interface 接口
接口指定了一个类型应该拥有的方法,并由该类型决定如何实现这些方法。
接口的声明
// create interface
type MyInterface interface {
do()string
//checkNumber(i int)(b bool)
}
// create struct zhangSan
type zhangSan struct {
name string
age int
}
// zhangSan implement MyInterface
func (zs zhangSan) do()string {
fmt.Println("This is do function : ",zs)
return ""
}
func main() {
zhangsan := zhangSan{name: "zhangSan",age: 18}
var myInterface MyInterface
myInterface = zhangsan // zhangSan 必须要实现所有的方法才可以 **如此赋值**
myInterface.do()
}
// 应用场景
// 创建计算接口
type Payroll interface {
countPayroll() int
}
type qianDuan struct { // struct 1
name string //姓名
payroll int //工资
pushMoney int //提成
}
type houDuan struct { // struct 2
name string
payroll int //工资
weal int //福利
}
// struct 1 implement Payroll
func (qd qianDuan) countPayroll()int {
inn := qd.payroll * qd.pushMoney
return qd.payroll+inn/100
}
// struct 2 implement Payroll
func (hd houDuan) countPayroll()int {
return hd.payroll+hd.weal
}
// one count total payroll function
func totalPayroll(p []Payroll) {
for _,v := range p{
fmt.Println("this is Payroll",v.countPayroll())
}
}
func main() {
totalPayroll([]Payroll{qianDuan{"张三",5000,30},houDuan{"李四",6000,1000}})
}
/* 输出
this is Payroll 6500
this is Payroll 7000
*/
空接口&&类型断言
空接口:没有方法的接口称为空接口,表示为
interface{}
,由于空接口没有方法,所以所有类型都实现了空接口
类型断言:用来获取接口的底层类值(实现该接口的数据类型);i.(T) T是类型;
1.对类型的断言;2.对接口实现的断言;
// 1.对类型的断言
func assert(i interface{}) {
// v 是实例,ok :true/false
v,ok := i.(int) // 断言这个i是int类型 当 s 是字符串时 断言就为false;
fmt.Println(v," : ",ok) // 60 : true
}
func main() {
//var s interface{} = 60 // 60 : true
var s interface{} = "60" // 0 : false
assert(s)
// 断言通用类型: type
switch s.(type) {
case int:
fmt.Println("this is int")
case string:
fmt.Println("this is string")
default:
fmt.Println("this is not find")
}
}
// 2.对接口实现的断言;
func checkType(i interface{}){
switch v:= i.(type) {
case Payroll:
fmt.Println("this is Payroll function result : ",v.countPayroll())
default:
fmt.Println("not find type")
}
}
func main() {
// 对接口实现的断言
checkType("string") //没有实现接口 Payroll
i := qianDuan{"lishi",5000,30}
checkType(i) // 实现了接口
}
/*
not find type
this is Payroll function result : 6500
*/
指针接口实现
// create interface
type MyInterfaces interface {
do()
}
// create struct zhangSan
type zhangSans struct {
name string
age int
}
// 使用值接受体实现接口
func (zs zhangSans) do(){
fmt.Println("this is zhangSans ",zs)
}
// create struct zhangSan
type liSi struct {
name string
age int
}
// 使用指针接受体实现接口
func (ls *liSi) do(){
fmt.Println("this is *liSi ",ls)
}
func main() {
zs1 := zhangSans{"张三",18}
zs2 := zhangSans{"张三2",18}
ls1 := liSi{"李四",18}
//ls2 := liSi{"李四2",18}
var myInterface MyInterfaces //创建接口实例
// myInterface.do() //因为没有具体的实例所以直接调用 报错:无效内存地址或空指针解引用
myInterface = zs1 // zs1实例赋值给该实例
myInterface.do() // this is zhangSans {张三 18}
myInterface = &ls1 //zs1实例赋值给该实例
myInterface.do() // this is *liSi &{李四 18}
// 使用值接受者声明的方法,既可以用值来调用,也能用指针调用
myInterface = &zs2
myInterface.do() // this is zhangSans {张三2 18}
// 编译报错 : 需要指针类型,因为liSi实现的接口类型是指针类型
//myInterface = ls2 // err: cannot use ls2 (type liSi) as type MyInterfaces in assignment:
}
1.实现接口一个接口,方法的接受体(或者说限制) 可以是指针或值;
2.当使用值作为实现方法接受体时,
// 接口类型调用方法时,其底层实例可以是实例的指针或值
// 方法中对实例的改动,不会对原实例造成影响
3.当使用指针作为实现方法接受体时,
// 接口类型调用方法时,其底层实例只能是实例的指针.
// 方法中对实例的改动,对原实例造成影响
实现多个接口
// 实现多个接口
type speak interface {
startSpeak()
}
type eat interface{
startEat()
}
type employee struct {
name string
address string
}
func (e employee)startSpeak() {
fmt.Println("speak interface:",e)
}
func (e employee)startEat() {
fmt.Println("eat interface:",e)
}
func main() {
operations := employee{"zhangsan","jiali"}
var s speak = operations
var e eat = operations
s.startSpeak()
e.startEat()
}
接口嵌套
type speak interface {
startSpeak()
}
type eat interface{
startEat()
}
type person interface {
speak
eat
}
type employee struct {
name string
address string
}
func (e employee)startSpeak() {
fmt.Println("speak interface:",e)
}
func (e employee)startEat() {
fmt.Println("eat interface:",e)
}
func main() {
operations := employee{"zhangsan","jiali"}
var p person = operations
p.startSpeak()
p.startEat()
}
接口的零值
接口的零值是
nil
。对于值为nil
的接口,其底层值(即实例)和具体类型(Concrete Type)都为nil
。